1.在同一個類中一個沒有事務 A 的方法調用另個有事務 B 的方法,那麼那個有事務 B 的方法是失效的;
public class test {
public void a() {
this.b();
}
@Transactional
public void b() {
/* … */
}
}
2.如果有事務 A 方法調用沒有(或者有)事務 B 的方法,那麼事務 A 都會生效,而方法 B 不會生效;
public class test {
@Transactional
public void a() {
this.b();
}
@Transactional
// @Transactional
public void b() {
/* … */
}
}
3.但是如果是不同類的話就都會生效;
總結
我們調用的方法A不帶註解,因此代理類不開事務,而是直接調用目標對象的方法。當進入目標對象的方法後,執行的上下文已經變成目標對象本身了,因爲目標對象的代碼是我們自己寫的,和事務沒有半毛錢關係,此時你再調用帶註解的方法,照樣沒有事務,只是一個普通的方法調用而已。簡單來說,內部調用本類方法,不會再走代理了,所以B的事務不起作用
解決方案:
- 可以將方法放入另一個類,並且該類通過spring注入,即符合了在對象之間調用的條件。
- 獲取本對象的代理對象,再進行調用。具體操作如:
1)Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy=“true”/>
2)在xxxServiceImpl中,用(xxxService)(AopContext.currentProxy()),獲取到xxxService的代理類,再調用事務方法,強行經過代理類,激活事務切面。public class test { @Transactional public void a() { (test)(AopContext.currentProxy()).b(); } @Transactional // @Transactional public void b() { /* … */ } }
- 當然也可以@Autowired 注入自己來調用方法解決。
- 把註解加到類名上面。