使用spring boot,涉及多表DML时,要保证事务一致,否则可能出现脏数据,一般我们用到的是Transactional注解,这里用一个数据库更新操作和大家一起探讨下下面5种情况事务的有效与否情况.。
语言:java
框架:springboot
版本:2.2.13.RELEASE
1.service有Transactional注解,方法中抛异常:
更新这一条数据
把rate更新为88
8/0处打断点后,显示update 1
再查一下数据,没有变,说明事务还未提交,因为加了Transactional注解,要走完整个逻辑才会提交事务:
执行错误代码后,抛出异常,由于之前还未提交事务, 所以数据没有更新。
2.service有Transactional,调用本地一个方法:
结果和第一种相同。
3.service调用本地一个方法,service不添加Transactional,那个本地方法上添加Transactional:
error打断点后,update执行完后数据已更新,说明没有Transactional注解,是不启用事务的
抛出异常,数据仍然是更新后的,说明没有回滚
再把private方法改成public方法:
结果也是事务没有回滚。
4.service中调用另一个service方法,当前调用方service不添加Transactional,被调用方service添加Transactional并抛异常;
update 1
抛出异常后
数据还是88,没有被回滚。因为Transactional注解只保证被加的service方法。
5.service中调用另一个service方法,当前调用方service不添加Transactional,被调用方service添加Transactional但不抛异常,当前调用方service抛异常;
结果也是数据被更新,没有回滚。
6.service中调用另一个service方法,当前调用方service添加Transactional,被调用方service不添加Transactional并抛异常;
结果和第一种一样。
经过上面的调查验证可以知道,如果要保证事务,需要在方法加Transactional注解,如果是在一个service中,则在service方法上加注解。如果是一个service调另一个service,两边都有DML操作,要保证数据一致,比如主子表的情况,要怎么处理呢。是否是在调用方service加Transactional即可?验证下:
请求后发现数据没有插入:
欢迎大家一起讨论。