@Transactional什麼時候開啟事物
在使用注解事務的情況時,Spring會把每個方法的執行封裝為AOP執行過程。
每次執行被事務注解方法時,會判斷是否有必要建立事務。如果建立事務成功,則繼續調用業務邏輯方法。
事務是在方法執行最開始階段建立的,是以方法要越小越好。
用法
spring-servlet.xml
1.spring-servlet.xml中添加tx名字空間
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
方式1
<!-- transaction support-->
<!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- PlatformTransactionMnager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
方式2
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSourceDefault">
<!-- 事務通知定義 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="batchAdd" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="delete" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="update" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="batchUpdate" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="mergeToTrunk" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="addToTrunk" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
<!-- AOP切面配置 -->
<aop:config>
<aop:pointcut id="serviceMethod" expression="execution( com.suning.tpp.service..*(..))" />
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />br/></aop:config>
測試代碼
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public ResourceBO detail(ResourceBO b) {
ExtPointTrunkBO extPointTrunkBO = new ExtPointTrunkBO();
String sysCode = "AIMP";
extPointTrunkBO.setTrunkVersion("1.3");
extPointTrunkBO.setSysCode(sysCode);
extPointTrunkBO.setVersion("1.4");
extPointTrunkService.add(extPointTrunkBO);
addExtPointImpl(sysCode);
int i = 1/0;
return super.detail(b);
}
// @Transactional(propagation = Propagation.MANDATORY)
public int addExtPointImpl(String sysCode) {
ExtPointImplTrunkBO extPointImplTrunkBO = new ExtPointImplTrunkBO();
extPointImplTrunkBO.setSysCode(sysCode);
extPointImplTrunkBO.setVersion("1.4");
extPointImplTrunkBO.setTrunkVersion("1.3");
return extPointImplTrunkService.add(extPointImplTrunkBO);
解釋含義
以上面的調用關系detail調用addExtPointImpl方法
Spring事務傳播屬性:
1.propagation-required: 支援目前事務,如果有就加入目前事務中;如果目前方法沒有事務,就建立一個事務;預設開啟此方式
detail加此注解在Spring封裝為AOP執行過程中,開啟事物(建立一個事物);addExtPointImpl加此注解要看調用方是否開啟事物了,
若開啟了事物就加入前事務中,如果沒開啟從這裡開始開啟事物
2.propagation-supports: 支援目前事務,如果有就加入目前事務中;如果目前方法沒有事務,就以非事務的方式執行;
detail加此注解在Spring封裝為AOP執行過程中,以非事務的方式執行;addExtPointImpl加此注解要看調用方是否開啟事物了,
若開啟了事物就加入前事務中,如果沒開啟則以非事務的方式執行
3.propagation-mandatory: 支援目前事務,如果有就加入目前事務中;如果目前沒有事務,就抛出異常;
detail加此注解,執行時報錯No existing transaction found for transaction marked with propagation 'mandatory';
addExtPointImpl加此注解要看調用方是否開啟事物了,若開啟了事物就加入前事務中,如果沒開啟則抛出異常
4.propagation-requires_new: 建立事務,如果目前存在事務,就把目前事務挂起;如果目前方法沒有事務,就建立事務;
5.propagation-not-supported: 以非事務方式執行,如果目前方法存在事務就挂起目前事務;如果目前方法不存在事務,就以非事務方式執行;
6.propagation-never: 以非事務方式執行,如果目前方法存在事務就抛出異常;如果目前方法不存在事務,就以非事務方式執行;
7.propagation-nested: 如果目前方法有事務,則在嵌套事務内執行;如果目前方法沒有事務,則與required操作類似;
關于事務挂起的舉例:(某事務挂起之後,任何操作都不在該事務的控制之下)
例如: 方法A支援事務,方法B不支援事務。 即PROPAGATION_NOT_SUPPORTED
方法A調用方法B。
在方法A開始運作時,系統為它建立Transaction,方法A中對于資料庫的處理操作,會在該Transaction的控制之下。
這時,方法A調用方法B,方法A打開的 Transaction将挂起,方法B中任何資料庫操作,都不在該Transaction的管理之下。
當方法B傳回,方法A繼續運作,之前的Transaction回複,後面的資料庫操作繼續在該Transaction的控制之下 送出或復原。