有時候,我們明明在類或者方法上添加了@Transactional注解,卻發現方法并沒有按事務處理,其實,以下場景會導致Spring的@Transactional事務失效,
1、事務方法所在的類沒有加載到Spring IOC容器中,
@Transactional是Spring的注解,未被Spring管理的類中的方法不受@Transactional注解控制,這個應該很好理解,
2、方法沒有被public修飾,
眾所周知,java的訪問權限修飾符有:private、default、protected、public四種,但是@Transactional注解只能作用于public修飾的方法上,具體為什么會這樣,我也沒理解,就先記住吧,
3、在同一個類中的方法呼叫@Transactional方法,
假如在同一個類中有A、B兩個方法,如下:
@Service public class UserServiceImpl { @Autowired UserMapper userMapper; public void A() { B(); } @Transactional public void B() { userMapper.deleteById(1); int i = 10 / 0; //模擬發生例外 } }
像上面的代碼,B方法使用@Transactional注解標注,在A()方法中呼叫了B()方法,在外部呼叫A()方法時,B()方法的事務不會生效,這是由于使用Spring AOP代理造成的,因為只有當事務方法被當前類以外的代碼呼叫時,才會由Spring生成的代理物件來管理,
4、方法的事務傳播型別不支持事務,
當@Transactional的propagation設定為NOT_SUPPORTED時,也就是@Transactional方法總是非事務方式執行,(Spring事務傳播行為可以查閱我之前的一篇文章:Spring事務(一)-事務傳播行為)
5、不正確地捕獲例外,
使用了try-catch代碼塊將例外捕捉了,沒有向上拋出例外,事務不會回滾,
6、標注錯誤的例外型別,
Spring事務默認回滾型別是RuntimeException型別,如果沒有制定回滾的型別,拋出的錯誤不是RuntimeException型別,則無法回滾,
7、資料庫不支持事務,
以MySQL為例,InnoDB引擎是支持事務的,而像MyISAM、MEMORY等是不支持事務的, 從MySQL5.5.5開始默認的存盤引擎是InnoDB,之前默認都是MyISAM,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508760.html
標籤:Java
