实践理解 Transactional 是否生效
示例:
新建一个订单表 tb_order_test 。
手动插入一条数据。
然后在代码中,根据 id 更新,如果更新成功,那么 update_time 会变化。
代码中执行 1/0; 由于 0不能做为除数,代码会抛异常。
通过 updateTime 观察事务是否提交/回滚。@Transactional 是否生效。
@Service
public class TransactionalDemo {@Resourceprivate OrderService orderService;// @Transactional(rollbackFor = Exception.class)public void doA() {doB();//0不能做为除数,此处会抛异常int value = 1/0;}@Transactional(rollbackFor = Exception.class)public void doB() {Order order = new Order();order.setId(123L);order.setUpdateTime(new Date());//根据 id 更新,如果更新成功,那么 updateTime 会变化。orderService.updateById(order);}}
A方法调用B方法,A没有@Transactional 注解,B有
执行A方法,抛异常后,update_time 已更新为最新时间,更新成功,说明事务没有回滚。@Transactional 不生效
@Transactional 底层是通过 AOP 动态代理实现的,如果在同一个类中调用,就不是通过代理类调用了,事务不会生效。
解决方法: 通过@Resource 注入自身服务再调用方法。比如类叫 XxService ,那么可以在 XxService 里面用 @Resource 注入 XxService 。
A方法调用B方法,A有@Transactional 注解,B也有
执行A方法,抛异常后,update_time 没有更新成功,说明事务回滚了。@Transactional 生效
A方法调用B方法,A有@Transactional 注解,B没有
执行A方法,抛异常后,update_time 没有更新成功,说明事务回滚了。@Transactional 生效
A方法调用B方法,A有@Transactional 注解,B没有。A方法 catch 异常
如果在 Service 服务层 catch异常,那么 @Transactional 会认为方法正常执行,没有异常,不会回滚。
@Transactional 不生效。
如果确认需要对 @Transactional 注解 的方法进行 catch,需要放到 Controller 层catch 异常。
参考资料:
https://blog.csdn.net/java_zyq/article/details/107656653
https://www.cnblogs.com/ibcdwx/p/16643034.html