实践理解 Transactional 是否生效

实践理解 Transactional 是否生效

示例:

新建一个订单表 tb_order_test 。

手动插入一条数据。

然后在代码中,根据 id 更新,如果更新成功,那么 update_time 会变化。

代码中执行 1/0; 由于 0不能做为除数,代码会抛异常。

通过 updateTime 观察事务是否提交/回滚。@Transactional 是否生效。

@Service
public class TransactionalDemo {

    @Resource
    private 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有@Transactional 注解,但是用 private 修饰

执行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

posted on 2023-07-14 11:16  乐之者v  阅读(78)  评论(0编辑  收藏  举报

导航