spring事務詳解(二)簡單樣例

系列目錄

spring事務詳解(一)初探事務html

spring事務詳解(二)簡單樣例spring

spring事務詳解(三)源碼詳解數據庫

spring事務詳解(四)測試驗證編程

spring事務詳解(五)總結提升ide

1、引子

在Spring中,事務有兩種實現方式:測試

  1. 編程式事務管理: 編程式事務管理使用底層源碼可實現更細粒度的事務控制。spring推薦使用TransactionTemplate,典型的模板模式。
  2. 申明式事務管理: 添加@Transactional註解,並定義傳播機制+回滾策略。基於Spring AOP實現,本質是對方法先後進行攔截,而後在目標方法開始以前建立或者加入一個事務,在執行完目標方法以後根據執行狀況提交或者回滾事務。

2、簡單樣例

需求:

建立用戶時,新建一個用戶餘額表。若是用戶餘額建立失敗拋出異常,那麼用戶表也回滾,即要保證「新增用戶+新增用戶餘額」一塊兒成功 或 回滾。this

2.1 申明式事務管理

以下圖,只須要在service.impl層,業務方法上添加@Transactional註解,定義事務的傳播機制爲REQUIRED(不寫這個參數,默認就是REQUIRED),遇到Exception異常就一塊兒回滾。spa

REQUIRED傳播機制下:存在加入事務,不存在建立新事務。保證了當前方法中的全部數據庫操做都在一個物理事務中,當遇到異常時會整個業務方法一塊兒回滾。code

 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配置也是同樣的)。以下: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(); 標識爲回滾。--》特殊狀況才使用

3、總結

spring支持的這兩種方式均可以,我的認爲大部分狀況下@Transactional能夠知足須要。

相關文章
相關標籤/搜索