@Transactional注解不生效的原因总结(整理网上和自己遇到的解决方案)
1、问题背景
今天做项目,发现配置好@Transactional后,没有生效,事务没有回滚,即便在网上查资料,也没有解决,好像网上没有人发过我遇见的这种情况的帖子。
2、自己遇到的情况分析
代码结构图
控制层代码
1 2 3 4 5 6 7 8 9 10 | @RequestMapping ( "/update" ) @ResponseBody public Object updateStu( int age) { try { transactionService.updateStudent(age); return "success" ; } catch (Exception e) { return e.getMessage(); } } |
TransactionServiceImpl内代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Service public class TransactionServiceImpl implements TransactionService { @Resource StudentServiceImpl studentService; @Transactional (rollbackFor = Exception. class ) public void updateStudent( int age) { Student stu1 = studentService.getStudentById( 1 ); Student stu2 = studentService.getStudentById( 2 ); stu1.setAge(age); stu2.setAge(age); studentService.updateStudent(stu1); int a = 1 / 0 ; studentService.updateStudent(stu2); } } |
applicationContext.xml中配置事务
1 2 3 4 | < bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> < property name="dataSource" ref="dataSource"/> </ bean > < tx:annotation-driven transaction-manager="transactionManager"/> |
最开始spring-mvc.xml配置的扫描包是:<context:component-scan base-package="com.zhi">,当运行程序后,访问controller,第一个更新操作事务没有回滚。
最后查找问题原因,是spring-mvc的包扫描问题。
启动程序,现根据spring监听创建spring上下文,在spring扫描包的时候,会将TransactionServiceImpl对象放进spring上下文中。然后程序会继续加载springmvc的配置,创建springmvc上下文,这是扫描包时,会将TransactionServiceImpl对象放入springmvc上下文中。当访问接口时,是由springmvc上下文中的controller从springmvc上下文中获取到TransactionServiceImpl对象。当执行到@Transactional注解的方法时,spring aop会判断是否创建代理对象。问题就在这里,因为事务在spring上下文中配置,但是获取到的对象时在springmvc上下文中,所以spring无法创建代理对象,因此@Transactional注解最终不会生效。
3、其他@Transactional不生效原因
参考:https://blog.csdn.net/qq_20597727/article/details/84900994
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步