標籤:div cti 生效 檔案 manage 直接 support xml配置 man
1. 首先spring聲明式事務的實現是通過AOP來實現的。spring聲明式事務有多種方式來聲明,其中最常用的是使用Spring的tx命名空間和@transactional註解來實現。
2. 在spring XML設定檔中,使用tx命名空間來配置spring事務,當然,aop一般也是要聲明的,因為有一些聲明式的事務配置元素是依賴於Spring的AOP配置元素;
- 我們可以使用tx:advice來配置事務,但更多的時候我們通過註解來實現,即tx:annotation-driven;
- tx:annotation-driven,預設會自動使用名稱為transactionManager的交易管理員,所以,如果定義的交易管理員名稱為transactionManager,那麼就可以直接使用<tx:annotation-driven/>,不用手動設定manager="transactionManager" 屬性;
3. spring同一個類中transactional註解無效分為兩種情況:
a. 外部方法調用A方法:這種情況下B的事務將不生效;
public class Test { public void A() { this.B(); } @Transactional public void B() { System.out.println(); }}
b. 外部方法調用A方法:這種情況下B的事務將不生效;
public class Test { @Transactional(propagation=Propagation.SUPPORTS) public void A() { this.B(); } @Transactional(propagation=Propagation.REQUIRED) public void B() { System.out.println(); }}
c. 原因是Spring的AOP是使用了一個代理對象來封裝目標對象,並攔截目標對象的方法調用。這樣的實現帶來的影響是: 在目標對象中調用自己類內部實現的方法時,spring會為該方法所在的bean動態產生一個代理類,當這個方法被調用時,實際上是代理類調用的,如果該方法有transactional註解,代理類在調用之前就會啟動transactional,如果沒有,代理類就不啟動事務。然而,如果這個有註解的方法是被同一個類中的其他方法調用的,那麼該方法的調用並沒有通過代理類,而是直接通過原來的那個bean,所以就不會啟動transaction,我們看到的現象就是@Transactional註解無效。
d. 解決方案,可以把這兩個方法放到兩個類中進行調用;也可以使用 AspectJ 模式的事務實現:<tx:annotation-driven mode="aspectj"/>
Spring聲明式事務