环境:springboot2.3.9.RELEASE

怀柔网站建设公司成都创新互联公司,怀柔网站设计制作,有大型网站制作公司丰富经验。已为怀柔上1000家提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的怀柔做网站的公司定做!
Spring提供两种编程式事务管理方法:
Spring官方推荐使用TransactionTemplate方式
- // 实体类
 - @Entity
 - @Table(name = "BC_USERS")
 - @Data
 - public class Users{
 - private String username ;
 - private String password ;
 - private Integer status = 0 ;
 - }
 - // DAO
 - public interface UsersRepository extends JpaRepository
 { - @Modifying
 - @Query("update Users u set u.status=?1,u.password='123123' where u.id=?2")
 - int updateUsers(Integer status, String id) ;
 - }
 - @Mapper
 - public interface UsersMapper {
 - int insertUser(Users user) ;
 - }
 - // Mapper.xml
 - insert into bc_users (id, username, password) values (#{id}, #{username}, #{password})
 
- @Service
 - public class UserService {
 - @Resource
 - private TransactionTemplate transactionTemplate ;
 - @Resource
 - private UsersRepository usersRepository ;
 - public Integer saveUsers(Users users) {
 - this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
 - Integer result = transactionTemplate.execute(new TransactionCallback
 () { - @Override
 - public Integer doInTransaction(TransactionStatus status) {
 - return usersMapper.insertUser(users) ;
 - }
 - }) ;
 - return result ;
 - }
 - }
 
当没有返回值时可以使用
TransactionCallbackWithoutResult
- public void saveUsers(Users users) {
 - transactionTemplate.execute(new TransactionCallbackWithoutResult() {
 - @Override
 - protected void doInTransactionWithoutResult(TransactionStatus status) {
 - usersMapper.insertUser(users) ;
 - }
 - }) ;
 - }
 
事务的回滚通过
TransactionStatus.setRollbackOnly方法
- public Users saveUser(Users users) {
 - return transactionTemplate.execute(new TransactionCallback
 () { - @Override
 - public Users doInTransaction(TransactionStatus status) {
 - try {
 - return usersMapper.insertUser(users) ;
 - } catch (Exception e) {
 - status.setRollbackOnly() ;
 - }
 - return null ;
 - }
 - }) ;
 - }
 
在实例化TransactionTemplate对象的时候我们可以对事务进行相关的属性配置,通过如下方式。
- private TransactionTemplate transactionTemplate ;
 - public UserService(PlatformTransactionManager transactionManager) {
 - this.transactionTemplate = new TransactionTemplate(transactionManager) ;
 - this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
 - this.transactionTemplate.setTimeout(30); //seconds
 - }
 
测试代码
- public Integer updateUsers(Integer statusValue, String id) {
 - return transactionTemplate.execute(new TransactionCallback
 () { - @Override
 - public Integer doInTransaction(TransactionStatus status) {
 - return usersRepository.updateUsers(statusValue, id) ;
 - }
 - }) ;
 - }
 - @Modifying
 - @Query("update Users u set u.status=?1 where u.id=?2")
 - int updateUsers(Integer status, String id) ;
 
由于这里事务传播属性设置的NOT_SUPPORTED.所以程序会报错误
- org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
 - at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:403)
 - at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
 - at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:531)
 
TransactionalOperator适用于反应式编程,这里不做介绍。
使用TransactionManager管理事务也有两种
PlatformTransactionManager,
ReactiveTransactionManager
ReactiveTransactionManager适用于反应式编程,这里不做介绍。
在程序中可以使用
PlatformTransactionManager来控制事务的提交与回滚
示例:
- private PlatformTransactionManager transactionManager ;
 - private DefaultTransactionDefinition definition ;
 - private TransactionStatus status ;
 - @Resource
 - private UsersRepository usersRepository ;
 - public UserService3(PlatformTransactionManager transactionManager) {
 - this.transactionManager = transactionManager ;
 - definition = new DefaultTransactionDefinition() ;
 - definition.setName("pgName") ;
 - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED) ;
 - }
 - public Integer saveUsers(Users users) {
 - TransactionStatus status = this.transactionManager.getTransaction(definition) ;
 - Integer result = null ;
 - try {
 - result = usersMapper.insertUser(users) ;
 - } catch (Exception e) {
 - transactionManager.rollback(status) ;
 - throw e ;
 - }
 - transactionManager.commit(status) ;
 - publisher.publishEvent(new UsersEvent(users));
 - return result ;
 - }
 
通过@
TransactionalEventListener注解监听事务的不同阶段的事件信息
- public @interface TransactionalEventListener {
 - TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
 - boolean fallbackExecution() default false;
 - @AliasFor(annotation = EventListener.class, attribute = "classes")
 - Class>[] value() default {};
 - @AliasFor(annotation = EventListener.class, attribute = "classes")
 - Class>[] classes() default {};
 - String condition() default "";
 - }
 
fallbackExecution: 默认值false;如果设置为true,当前即便没有事务也会触发事件。
TransactionPhase:默认值是事务提交以后;有如下几个取值:
- public enum TransactionPhase {
 - BEFORE_COMMIT, // 事务提交前触发
 - AFTER_COMMIT, // 事务提交后触发
 - AFTER_ROLLBACK, // 事务回滚触发
 - AFTER_COMPLETION // 事务完成后 触发
 - }
 
注意:@
TransactionalEventListener注解只对声明式事务起作用,对编程式事务无效。仅适用于由PlatformTransactionManager管理的线程绑定事务
示例:
- // 事件监听
 - @Component
 - public class TxListenerComponent {
 - @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
 - public void handleUsersAfterCommit(UsersEvent usersEvent) {
 - Users user = (Users) usersEvent.getSource() ;
 - System.out.println("AfterCommit收到事件通知:" + user.getPassword()) ;
 - }
 - @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
 - public void handleUsersAfterCompletion(UsersEvent usersEvent) {
 - Users user = (Users) usersEvent.getSource() ;
 - System.out.println("AfterCompletion收到事件通知:" + user.getPassword()) ;
 - }
 - @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
 - public void handleUsersAfterRollback(UsersEvent usersEvent) {
 - Users user = (Users) usersEvent.getSource() ;
 - System.out.println("AfterRollback收到事件通知:" + user.getPassword()) ;
 - }
 - @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
 - public void handleUsersBeforeCommit(UsersEvent usersEvent) {
 - Users user = (Users) usersEvent.getSource() ;
 - System.out.println("BeforeCommit收到事件通知:" + user.getPassword()) ;
 - }
 - }
 - // 发布事件
 - @Resource
 - private ApplicationEventPublisher publisher ;
 - @Resource
 - private UsersMapper usersMapper ;
 - public Integer saveUsers(Users users) {
 - Integer result = transactionTemplate.execute(new TransactionCallback
 () { - @Override
 - public Integer doInTransaction(TransactionStatus status) {
 - return usersMapper.insertUser(users) ;
 - }
 - }) ;
 - publisher.publishEvent(new UsersEvent(users));
 - return result ;
 - }
 
运行结果:
- 2021-06-17 14:02:56.830 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : ==> Preparing: insert into bc_users (id, username, password) values (?, ?, ?)
 - 2021-06-17 14:02:56.840 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : ==> Parameters: mmmmm(String), mmmmm(String), mmmmm(String)
 - 2021-06-17 14:02:56.842 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser : <== Updates: 1
 - BeforeCommit收到事件通知:mmmmm
 - AfterCommit收到事件通知:mmmmm
 - AfterCompletion收到事件通知:mmmmm
 
总结:编程式的事务适合少量的事务操作;比如在一个服务的调用中有大量的计算操作,最后将计算结果进行事务的操作这种情况就适合应用事务编程式的进行事务控制。如果一个操作有很多的事务的操作那声明式的事务方式就更加的合适。
                文章标题:Springboot编程式事务使用方式详解
                
                网站地址:http://www.csdahua.cn/qtweb/news12/507512.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网