spring事務詳解(二)簡單樣例
阿新 • • 發佈:2018-12-12
系列目錄
spring事務詳解(四)測試驗證
spring事務詳解(五)總結提高
一、引子
在Spring中,事務有兩種實現方式:
- 程式設計式事務管理: 程式設計式事務管理使用底層原始碼可實現更細粒度的事務控制。spring推薦使用TransactionTemplate,典型的模板模式。
- 申明式事務管理: 新增@Transactional註解,並定義傳播機制+回滾策略。基於Spring AOP實現,本質是對方法前後進行攔截,然後在目標方法開始之前建立或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。
二、簡單樣例
需求:
建立使用者時,新建一個使用者餘額表。如果使用者餘額建立失敗丟擲異常,那麼使用者表也回滾,即要保證“新增使用者+新增使用者餘額”一起成功 或 回滾。
2.1 申明式事務管理
如下圖,只需要在service.impl層,業務方法上新增@Transactional註解,定義事務的傳播機制為REQUIRED(不寫這個引數,預設就是REQUIRED),遇到Exception異常就一起回滾。
REQUIRED傳播機制下:存在加入事務,不存在建立新事務。保證了當前方法中的所有資料庫操作都在一個物理事務中,當遇到異常時會整個業務方法一起回滾。
1 /** 2 * 建立使用者並建立賬戶餘額 3 * 4 * @param name 5 * @param balance 6 *@return 7 */ 8 @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class) 9 @Override 10 public void addUserBalanceAndUser(String name, BigDecimal balance) { 11 log.info("[addUserBalanceAndUser] begin!!!"); 12 //1.新增使用者 13 userService.addUser(name);14 //2.新增使用者餘額 15 UserBalance userBalance = new UserBalance(); 16 userBalance.setName(name); 17 userBalance.setBalance(new BigDecimal(1000)); 18 this.addUserBalance(userBalance); 19 log.info("[addUserBalanceAndUser] end!!!"); 20 }
2.2 程式設計式事務管理
程式設計式事務管理,我們使用Spring推薦的transactionTemplate。我這裡因為使用的是spring cloud的註解配置,實現用了自動配置類配置好了TransactionTemplate這個型別的bean.使用的時候直接注入bean使用即可(當然老式的xml配置也是一樣的)。如下:
1 /** 2 * 建立使用者並建立賬戶餘額(手動事務,不帶結果) 3 * 4 * @param name 5 * @param balance 6 * @return 7 */ 8 @Override 9 public void addUserBalanceAndUserWithinTT(String name, BigDecimal balance) { 10 //實現一個沒有返回值的事務回撥 11 transactionTemplate.execute(new TransactionCallbackWithoutResult() { 12 @Override 13 protected void doInTransactionWithoutResult(TransactionStatus status) { 14 try { 15 log.info("[addUserBalanceAndUser] begin!!!"); 16 17 //1.新增使用者 18 userService.addUser(name); 19 //2.新增使用者餘額 20 UserBalance userBalance = new UserBalance(); 21 userBalance.setName(name); 22 userBalance.setBalance(new BigDecimal(1000)); 23 userBalanceRepository.insert(userBalance); 24 log.info("[addUserBalanceAndUser] end!!!"); 25 //注意:這裡catch住異常後,設定setRollbackOnly,否則事務不會滾。當然如果不需要自行處理異常,就不要catch了 26 } catch (Exception e) { 27 // 異常回滾 28 status.setRollbackOnly(); 29 log.error("異常回滾!,e={}",e); 30 } 31 32 } 33 }); 34 }
注意:
1.可以不用try catch,transactionTemplate.execute自己會捕捉異常並回滾。--》推薦
2.如果有業務異常需要特殊處理,記得:status.setRollbackOnly(); 標識為回滾。--》特殊情況才使用
三、總結
spring支援的這兩種方式都可以,個人認為大部分情況下@Transactional可以滿足需要。