技術分析之Spring框架的事務管理相關的類和API
1. PlatformTransactionManager接口 -- 平臺事務管理器.(真正管理事務的類)。該接口有具體的實現類,根據不同的持久層框架,需要選擇不同的實現類!
2. TransactionDefinition接口 -- 事務定義信息.(事務的隔離級別,傳播行爲,超時,只讀)
3. TransactionStatus接口 -- 事務的狀態
4. 總結:上述對象之間的關係:平臺事務管理器真正管理事務對象.根據事務定義的信息TransactionDefinition 進行事務管理,在管理事務中產生一些狀態.將狀態記錄到TransactionStatus中
5. PlatformTransactionManager接口中實現類和常用的方法
1. 接口的實現類
* 如果使用的Spring的JDBC模板或者MyBatis框架,需要選擇DataSourceTransactionManager實現類
* 如果使用的是Hibernate的框架,需要選擇HibernateTransactionManager實現類
2. 該接口的常用方法
* void commit(TransactionStatus status)
* TransactionStatus getTransaction(TransactionDefinition definition)
* void rollback(TransactionStatus status)
6. TransactionDefinition
1. 事務隔離級別的常量
* static int ISOLATION_DEFAULT -- 採用數據庫的默認隔離級別
* static int ISOLATION_READ_UNCOMMITTED
* static int ISOLATION_READ_COMMITTED
* static int ISOLATION_REPEATABLE_READ
* static int ISOLATION_SERIALIZABLE
2. 事務的傳播行爲常量(不用設置,使用默認值)
* 先解釋什麼是事務的傳播行爲:解決的是業務層之間的方法調用!!
* PROPAGATION_REQUIRED(默認值) -- A中有事務,使用A中的事務.如果沒有,B就會開啓一個新的事務,將A包含進來.(保證A,B在同一個事務中),默認值!!
* PROPAGATION_SUPPORTS -- A中有事務,使用A中的事務.如果A中沒有事務.那麼B也不使用事務.
* PROPAGATION_MANDATORY -- A中有事務,使用A中的事務.如果A沒有事務.拋出異常.
* PROPAGATION_REQUIRES_NEW(記)-- A中有事務,將A中的事務掛起.B創建一個新的事務.(保證A,B沒有在一個事務中)
* PROPAGATION_NOT_SUPPORTED -- A中有事務,將A中的事務掛起.
* PROPAGATION_NEVER -- A中有事務,拋出異常.
* PROPAGATION_NESTED(記) -- 嵌套事務.當A執行之後,就會在這個位置設置一個保存點.如果B沒有問題.執行通過.如果B出現異常,運行客戶根據需求回滾(選擇回滾到保存點或者是最初始狀態)
技術分析之Spring框架的事務管理的分類
1. Spring的事務管理的分類
1. Spring的編程式事務管理(不推薦使用)
* 通過手動編寫代碼的方式完成事務的管理(不推薦)
2. Spring的聲明式事務管理(底層採用AOP的技術)
* 通過一段配置的方式完成事務的管理(重點掌握註解的方式)
技術分析之Spring框架的事務管理之編程式的事務管理(瞭解)
1. 說明:Spring爲了簡化事務管理的代碼:提供了模板類 TransactionTemplate,所以手動編程的方式來管理事務,只需要使用該模板類即可!!
2. 手動編程方式的具體步驟如下:
1. 步驟一:配置一個事務管理器,Spring使用PlatformTransactionManager接口來管理事務,所以咱們需要使用到他的實現類!!
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2. 步驟二:配置事務管理的模板
<!-- 配置事務管理的模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
3. 步驟三:在需要進行事務管理的類中,注入事務管理的模板.
<bean id="accountService" class="com.demo1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
4. 步驟四:在業務層使用模板管理事務:
// 注入事務模板對象
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void pay(final String out, final String in, final double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 扣錢
accountDao.outMoney(out, money);
int a = 10/0;
// 加錢
accountDao.inMoney(in, money);
}
});
}
Spring框架的事務管理之基於AspectJ的XML方式(重點掌握)
1. 配置事務管理器
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2. 配置事務增強(增強規則)
<!-- 配置事務增強,通知部分(屬於AOP中的通知角色) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
name :綁定事務的方法名,可以使用通配符,可以配置多個。
propagation :傳播行爲
isolation :隔離級別
read-only :是否只讀
timeout :超時信息
rollback-for:發生哪些異常回滾.
no-rollback-for:發生哪些異常不回滾.
-->
<!-- 哪些方法加事務,可以使用通配符*,例如:pay* -->
<tx:method name="pay" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--aop方式,必須加上-->
<aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"/>
3. 配置AOP的切面(即哪些方法增強):切入點和通知結合
<!-- 配置AOP切面產生代理 -->
<aop:config>
<aop:advisor advice-ref="myAdvice" pointcut="execution(* com.demo2.AccountServiceImpl.pay(..))"/>
</aop:config>
* 注意:如果是自己編寫的切面,使用<aop:aspect>標籤,如果是系統製作的,使用<aop:advisor>標籤。
4. 編寫測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Demo2 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void run1(){
accountService.pay("冠希", "美美", 1000);
}
}
Spring框架的事務管理之基於AspectJ的註解方式(重點掌握,最簡單的方式)
1. 配置事務管理器
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2. 開啓註解事務
<!-- 開啓註解事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
3. 在業務層上添加一個註解:@Transactional,類或者方法上加都可以
4. 編寫測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class Demo3 {
@Resource(name="accountService")
private AccountService accountService;
@Test
public void run1(){
accountService.pay("冠希", "美美", 1000);
}
}
@Transactional
public class AccountServiceImpl implements AccountService{
...
}
手動回滾事務
如果在註解事物中需要回滾事物怎麼辦?
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();