@Transactional 注解相信大家并不陌生使套,平時(shí)開發(fā)中很常用的一個(gè)注解,它能保證方法內(nèi)多個(gè)數(shù)據(jù)庫操作要么同時(shí)成功鞠柄、要么同時(shí)失敗侦高。使用@Transactional注解時(shí)需要注意許多的細(xì)節(jié),不然你會(huì)發(fā)現(xiàn)@Transactional總是莫名其妙的就失效了厌杜。
今天開發(fā)的時(shí)候遇到這樣一個(gè)問題奉呛,同一個(gè)類里面的方法調(diào)用计螺,比如有一個(gè)類Test,它的一個(gè)方法A瞧壮,A再調(diào)用本類的方法B(不論方法B是用public還是private修飾)登馒,但方法A沒有聲明注解事務(wù),而B方法有咆槽。則外部調(diào)用方法A之后陈轿,方法B的事務(wù)是不會(huì)起作用的。
但是同一個(gè)類中方法的內(nèi)部調(diào)用是很常見的秦忿,遇到這種問題怎么處理麦射?我們可以把代理類再次注入進(jìn)來,案例如下:
除了上面的情況會(huì)造成事務(wù)的失效灯谣,例如:如果B方法內(nèi)部拋了異常潜秋,而A方法此時(shí)try catch了B方法的異常,那這個(gè)事務(wù)還能正程バ恚回滾嗎峻呛?答案也是不能。案例如下:
@Transactional是否有效總結(jié)
1.@Transactional 加于private方法, 無效
2.@Transactional 加于未加入接口的public方法, 再通過普通接口方法調(diào)用, 無效
3.@Transactional 加于接口方法, 無論下面調(diào)用的是private或public方法, 都有效
4.@Transactional 加于接口方法后, 被本類普通接口方法直接調(diào)用, 無效
5.@Transactional 加于接口方法后, 被本類普通接口方法通過接口調(diào)用, 有效
6.@Transactional 加于接口方法后, 被它類的接口方法調(diào)用, 有效
7.@Transactional 加于接口方法后, 被它類的私有方法調(diào)用后, 有效
總結(jié): Transactional是否生效, 僅取決于是否加載于接口方法, 并且是否通過接口方法調(diào)用(而不是本類調(diào)用)
當(dāng)我們想判斷一個(gè)方法中的事務(wù)是否生效時(shí)辜窑,我們可以在方法中加入下面的代碼:
TransactionSynchronizationManager.isActualTransactionActive()
當(dāng)上面的方法返回值為true時(shí)表明存在事務(wù)钩述,返回值為false時(shí)說明不存在事務(wù)。