天天看點

@Transactional的使用

@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的控制之下 送出或復原。

繼續閱讀