成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Springboot編程式事務使用方式詳解

開發 前端
編程式的事務適合少量的事務操作;比如在一個服務的調用中有大量的計算操作,最后將計算結果進行事務的操作這種情況就適合應用事務編程式的進行事務控制。

[[410883]]

環境:springboot2.3.9.RELEASE

Spring提供兩種編程式事務管理方法:

  1. 使用TransactionTemplate 或 TransactionalOperator
  2. 直接創建TransactionManager的實現

Spring官方推薦使用TransactionTemplate方式

準備

  1. // 實體類 
  2. @Entity 
  3. @Table(name = "BC_USERS"
  4. @Data 
  5. public class Users{ 
  6.     private String username ; 
  7.     private String password ; 
  8.     private Integer status = 0 ; 
  9. // DAO 
  10. public interface UsersRepository extends JpaRepository<Users, String> { 
  11.  
  12.   @Modifying 
  13.   @Query("update Users u set u.status=?1,u.password='123123' where u.id=?2"
  14.   int updateUsers(Integer status, String id) ; 
  15.      
  16. @Mapper 
  17. public interface UsersMapper { 
  18.  
  19.   int insertUser(Users user) ; 
  20.      
  21. // Mapper.xml 
  22. <insert id="insertUser" parameterType="com.pack.domain.Users"
  23.   insert into bc_users (id, username, passwordvalues (#{id}, #{username}, #{password}) 
  24. </insert

1 TransactionTemplate

1.1 有返回值的

  1. @Service 
  2. public class UserService { 
  3.      
  4.   @Resource 
  5.   private TransactionTemplate transactionTemplate ; 
  6.   @Resource 
  7.   private UsersRepository usersRepository ; 
  8.      
  9.   public Integer saveUsers(Users users) { 
  10.     this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 
  11.     Integer result = transactionTemplate.execute(new TransactionCallback<Integer>() { 
  12.       @Override 
  13.       public Integer doInTransaction(TransactionStatus status) { 
  14.         return usersMapper.insertUser(users) ; 
  15.       } 
  16.     }) ; 
  17.     return result ; 
  18.     } 
  19.      

1.2 無返回值的

當沒有返回值時可以使用

TransactionCallbackWithoutResult

  1. public void saveUsers(Users users) { 
  2.   transactionTemplate.execute(new TransactionCallbackWithoutResult() { 
  3.     @Override 
  4.     protected void doInTransactionWithoutResult(TransactionStatus status) { 
  5.       usersMapper.insertUser(users) ; 
  6.     } 
  7.   }) ; 

1.3 事務回滾

事務的回滾通過

TransactionStatus.setRollbackOnly方法

  1. public Users saveUser(Users users) { 
  2.   return transactionTemplate.execute(new TransactionCallback<Users>() { 
  3.     @Override 
  4.     public Users doInTransaction(TransactionStatus status) { 
  5.       try { 
  6.         return usersMapper.insertUser(users) ; 
  7.       } catch (Exception e) { 
  8.         status.setRollbackOnly() ; 
  9.       } 
  10.       return null ; 
  11.     } 
  12.   }) ; 

1.4 配置事務屬性

在實例化TransactionTemplate對象的時候我們可以對事務進行相關的屬性配置,通過如下方式。

  1. private TransactionTemplate transactionTemplate ; 
  2.      
  3. public UserService(PlatformTransactionManager transactionManager) { 
  4.   this.transactionTemplate = new TransactionTemplate(transactionManager) ; 
  5.   this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); 
  6.   this.transactionTemplate.setTimeout(30); //seconds 

測試代碼

  1. public Integer updateUsers(Integer statusValue, String id) { 
  2.   return transactionTemplate.execute(new TransactionCallback<Integer>() { 
  3.     @Override 
  4.     public Integer doInTransaction(TransactionStatus status) { 
  5.       return usersRepository.updateUsers(statusValue, id) ; 
  6.     } 
  7.   }) ; 
  8. @Modifying 
  9. @Query("update Users u set u.status=?1 where u.id=?2"
  10. int updateUsers(Integer status, String id) ; 

由于這里事務傳播屬性設置的NOT_SUPPORTED.所以程序會報錯誤

  1. org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 
  2.     at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:403) 
  3.     at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257) 
  4.     at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:531) 

2 TransactionalOperator

TransactionalOperator適用于反應式編程,這里不做介紹。

3 TransactionManager

使用TransactionManager管理事務也有兩種

PlatformTransactionManager,

ReactiveTransactionManager

ReactiveTransactionManager適用于反應式編程,這里不做介紹。

3.1 PlatformTransactionManager

在程序中可以使用

PlatformTransactionManager來控制事務的提交與回滾

示例:

  1. private PlatformTransactionManager transactionManager ; 
  2. private DefaultTransactionDefinition definition ; 
  3. private TransactionStatus status ; 
  4. @Resource 
  5. private UsersRepository usersRepository ; 
  6.  
  7. public UserService3(PlatformTransactionManager transactionManager) { 
  8.   this.transactionManager = transactionManager ; 
  9.   definition = new DefaultTransactionDefinition() ; 
  10.   definition.setName("pgName") ; 
  11.   definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED) ; 
  12.      
  13. public Integer saveUsers(Users users) { 
  14.   TransactionStatus status = this.transactionManager.getTransaction(definition) ; 
  15.   Integer result = null ; 
  16.   try { 
  17.     result = usersMapper.insertUser(users) ; 
  18.   } catch (Exception e) { 
  19.     transactionManager.rollback(status) ; 
  20.     throw e ; 
  21.   } 
  22.   transactionManager.commit(status) ; 
  23.   publisher.publishEvent(new UsersEvent(users)); 
  24.   return result ;        

4 事務事件監聽

通過@

TransactionalEventListener注解監聽事務的不同階段的事件信息

  1. public @interface TransactionalEventListener { 
  2.   TransactionPhase phase() default TransactionPhase.AFTER_COMMIT; 
  3.   boolean fallbackExecution() default false
  4.   @AliasFor(annotation = EventListener.class, attribute = "classes"
  5.   Class<?>[] value() default {}; 
  6.   @AliasFor(annotation = EventListener.class, attribute = "classes"
  7.   Class<?>[] classes() default {}; 
  8.   String condition() default ""

fallbackExecution: 默認值false;如果設置為true,當前即便沒有事務也會觸發事件。

TransactionPhase:默認值是事務提交以后;有如下幾個取值:

  1. public enum TransactionPhase { 
  2.   BEFORE_COMMIT, // 事務提交前觸發 
  3.   AFTER_COMMIT, // 事務提交后觸發 
  4.   AFTER_ROLLBACK, // 事務回滾觸發 
  5.   AFTER_COMPLETION // 事務完成后 觸發 

注意:@

TransactionalEventListener注解只對聲明式事務起作用,對編程式事務無效。僅適用于由PlatformTransactionManager管理的線程綁定事務

示例:

  1. // 事件監聽 
  2. @Component 
  3. public class TxListenerComponent { 
  4.   @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) 
  5.   public void handleUsersAfterCommit(UsersEvent usersEvent) { 
  6.     Users user = (Users) usersEvent.getSource() ; 
  7.     System.out.println("AfterCommit收到事件通知:" + user.getPassword()) ; 
  8.   } 
  9.   @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) 
  10.   public void handleUsersAfterCompletion(UsersEvent usersEvent) { 
  11.     Users user = (Users) usersEvent.getSource() ; 
  12.     System.out.println("AfterCompletion收到事件通知:" + user.getPassword()) ; 
  13.   } 
  14.  
  15.   @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK) 
  16.   public void handleUsersAfterRollback(UsersEvent usersEvent) { 
  17.     Users user = (Users) usersEvent.getSource() ; 
  18.     System.out.println("AfterRollback收到事件通知:" + user.getPassword()) ; 
  19.   } 
  20.  
  21.   @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT) 
  22.   public void handleUsersBeforeCommit(UsersEvent usersEvent) { 
  23.     Users user = (Users) usersEvent.getSource() ; 
  24.     System.out.println("BeforeCommit收到事件通知:" + user.getPassword()) ; 
  25.   } 
  26. // 發布事件 
  27. @Resource 
  28. private ApplicationEventPublisher publisher ; 
  29. @Resource 
  30. private UsersMapper usersMapper ; 
  31.  
  32. public Integer saveUsers(Users users) { 
  33.   Integer result = transactionTemplate.execute(new TransactionCallback<Integer>() { 
  34.     @Override 
  35.     public Integer doInTransaction(TransactionStatus status) { 
  36.       return usersMapper.insertUser(users) ; 
  37.     } 
  38.   }) ; 
  39.   publisher.publishEvent(new UsersEvent(users)); 
  40.   return result ; 

運行結果:

  1. 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 (?, ?, ?) 
  2. 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) 
  3. 2021-06-17 14:02:56.842 DEBUG 10000 --- [nio-8081-exec-1] com.pack.mapper.UsersMapper.insertUser   : <==    Updates: 1 
  4. BeforeCommit收到事件通知:mmmmm 
  5. AfterCommit收到事件通知:mmmmm 
  6. AfterCompletion收到事件通知:mmmmm 

總結:編程式的事務適合少量的事務操作;比如在一個服務的調用中有大量的計算操作,最后將計算結果進行事務的操作這種情況就適合應用事務編程式的進行事務控制。如果一個操作有很多的事務的操作那聲明式的事務方式就更加的合適。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-02-21 11:21:40

golang編程語言

2023-04-28 08:21:36

SpringBoot聲明式事務編程式事務

2023-09-27 16:22:51

SpringMySQL原子性

2023-06-28 08:25:14

事務SQL語句

2009-12-25 18:05:05

Linux壓縮程式

2022-09-12 22:27:05

編程式事務聲明式事務對象

2023-09-04 08:00:53

提交事務消息

2022-10-25 18:00:00

Redis事務生產事故

2021-04-15 08:01:27

Spring聲明式事務

2019-11-27 10:05:00

LombokJava編程

2009-06-17 14:57:11

Spring事務管理

2023-02-10 07:00:22

2010-03-11 09:34:31

Python線程編程

2010-01-11 17:30:40

VB.NET播放聲音

2016-01-18 10:49:13

Java EE編程式Websocket

2015-09-09 18:02:07

PythonAPM

2024-11-06 09:26:48

SpringprofileENV

2010-06-22 13:23:18

Linux at命令詳

2009-08-03 11:38:57

linux at命令詳linux at命令

2023-11-10 09:16:45

SpringBootThymeleaf
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品亚洲二区 | 久久国产精品免费 | 美国a级毛片免费视频 | 欧美性受xxxx | 羞羞涩涩在线观看 | 日韩在线观看中文字幕 | 国产一区在线免费 | 久久久综合精品 | 国产精品精品3d动漫 | 欧美精品久久久久 | 亚洲视频在线观看免费 | 91在线精品一区二区 | 欧美vide| 国产激情在线 | 91观看| 国产精品国产精品国产专区不卡 | 久久夜色精品国产 | 欧美综合国产精品久久丁香 | 狠狠操在线| 久久1区| 久草欧美视频 | 日韩欧美一级 | 免费电影av| 91精品国产91久久综合桃花 | 91精品国模一区二区三区 | 欧美理论片在线 | 国产成人精品一区二 | 91日日| 国产精品久久久久久婷婷天堂 | 成人午夜免费在线视频 | 国产精品日韩在线观看 | 欧美精品综合在线 | 欧美精品日韩精品 | 国产成人精品免高潮在线观看 | 日韩三级 | 欧美天天视频 | 国产综合久久 | 一级毛片成人免费看a | 日韩精品一区二区三区中文在线 | 神马影院一区二区三区 | 亚洲精品乱码久久久久久按摩 |