实践理解 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 异常。