事物失效的8種情況及解決辦法


事物失效的8種情況及解決辦法

數據庫引擎不支持事務

這里以 MySQL 為例,其 MyISAM 引擎是不支持事務操作的,InnoDB 才是支持事務的引擎,一般要支持事務都會使用 InnoDB,這時候選擇支持事物的數據庫即可(好像是廢話,哈哈哈)

沒有被 Spring 管理

這個好像沒什么可說的,脫離了Spring的管理,還談什么Spring事物管理。

方法不是 public 的

@Transactional 只能用於 public 的方法上,否則事務不會失效,如果要用在非 public 方法上,可以開啟 AspectJ 代理模式。

數據源沒有配置事務管理器

相當於沒開啟事務管理,如果不是Springboot情況需要進行如下操作。

@Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }

如果是SpringBoot,在啟動類上直接加上注解@EnableTransactionManagement即可。

傳播特性配錯了

傳播特性配置成,Propagation.NOT_SUPPORTED或者Propagation.NOT_SUPPORTED,改成支持事物的傳播特性即可。

異常類型錯誤

因為默認的異常類型是運行時異常,如果拋出了其他異常就不生效。
解決方式:
1、將異常改成運行時異常
2、指定異常進行事物回滾,如:@Transactional(rollbackFor = Exception.class)

異常被吃掉了

如果你代碼這么寫,事物不生效:

    @Transactional(rollbackFor = Exception.class) public void updateUser2() { try { int r1 = userInfoDAO.updateUserName(1,"3"); int r2 = userInfoDAO.updateUserName(2,"4"); if (r2==1){ throw new RuntimeException(); } }catch (Exception e){ } }

 

解決辦法: 必須要拋出異常,否則Spring事務管理,不會走到回滾邏輯

類內部調用

 

@Service public class UserInfoService { public void justUpdate(){ updateUser2(); } @Transactional(rollbackFor = Exception.class) public void updateUser2() { } }

 

上述代碼不生效,因為內部調用不會涉及到代理類的調用,更不會有AOP的增強,因此不會生效。
解決辦法:
1、自注入

@Service public class UserInfoService { @Autowired private UserInfoService userInfoService; public void justUpdate(){ userInfoService.updateUser2(); } @Transactional(rollbackFor = Exception.class) public void updateUser2() { } }

 

2、Spring上下文

@Service public class UserInfoService { ApplicationContext applicationContext; public void justUpdate(){ UserInfoService userInfoService = (UserInfoService) applicationContext.getBean("userInfoService"); userInfoService.updateUser2(); } @Transactional(rollbackFor = Exception.class) public void updateUser2() { } }

 

3、獲取他的代理類,直接調用代理類

 

@Service public class UserInfoService { public void justUpdate(){ ((UserInfoService) AopContext.currentProxy()).updateUser2(); } @Transactional(rollbackFor = Exception.class) public void updateUser2() { } }

 

\


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM