Spring整合MyBatis 事務管理
前言
spring事務管理包含兩種情況,程式設計式事務、宣告式事務。而宣告式事務又包括基於註解@Transactional和tx+aop的方式。那麼本文先分析程式設計式註解事務和基於註解的宣告式事務。 程式設計式事務管理使用TransactionTemplate或者PlatformTransactionManager。對於程式設計式事務spring推薦使用TransactionTemplate。
一、程式設計式事務
spring事務特性
spring中所有的事務策略類都繼承自org.springframework.transaction.PlatformTransactionManager介面
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
程式設計式事務TransactionTemplate需要手動在程式碼中處理事務,一般不推薦使用,也不符合spring的思想,因為它直接耦合程式碼,但各有利弊。先看下TransactionTemplate的原始碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
|
從上面的程式碼可以看到核心方法是execute,該方法入參TransactionCallback<T>。檢視TransactionCallback原始碼:
1 2 3 |
|
那麼以上兩個原始碼可以確定我們使用程式設計式事務管理的方式也就是自己需要重寫doInTransaction()。OK,那麼我們手動使用TransactionTemplate處理下。
1、先配置transactionmanager
<!--事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
2、配置transactionTemplate
<!--程式設計式事務,推薦使用TransactionTemplate--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean>
3、業務程式碼處理
@Autowired private TransactionTemplate transactionTemplate; public int insertUser2(final User user) { Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus transactionStatus) { int i = userMapper.insertUser(user); if (i > 0) { System.out.println("success"); } int j = 10 / 0; return i; } }); return i; }
業務程式碼中我們使用by zero的異常故意丟擲,你會發現能繼續列印success,當你斷點debug時,你會發現資料庫一直是鎖定狀態,直到你程式執行完。如下圖:
二、基於Transactional註解的事務管理
當前應該是使用最清爽的事務管理方式了,也符合spring的理念,非入侵程式碼的方式。
1、配置
<!--事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 使用註解事務,需要新增Transactional註解屬性 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--啟用最新的註解器、對映器--> <mvc:annotation-driven/>
2、配置後只需要在要處理的地方加上Transactional註解,而且Transactional註解的方式可以應用在類上,也可以應用在方法上,當然只針對public方法。
3、業務程式碼處理
@Transactional public int insertUser(User user) { int i = userMapper.insertUser(user); if (i > 0) { System.out.println("success"); } int j = 10 / 0; return i; }