有关@Transactional注解的一些摸索

本文深入探讨了Spring框架中@Transactional注解的使用,特别是在不同传播行为下(如REQUIRED和REQUIRES_NEW)事务如何影响数据库操作。通过具体代码示例,展示了在方法A中调用方法B时,事务的开启、挂起及回滚机制,揭示了在出现异常情况下,数据库数据的最终状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先抛出问题:

① 一个有事务的方法A(insert)中又调用了一个有事务的方法B(insert2),B成功了,A报错.问:数据库有数据么?有几条?

@Transactional
public int insert(Stu stu) {
   insert2(stu);
   stu.setStuId(GuoUtil.getUUID());
   System.out.println(1/0); // 故意制造异常
   return stuMapper.insertSelective(stu);
}
@Transactional
public int insert2(Stu stu) {
   stu.setStuId(GuoUtil.getUUID());
   return stuMapper.insertSelective(stu);
}

经过我的测试:结果数据库一条数据都没有.

首先需要搞明白@Transactional的默认传播行为.

主要我分析了两个:

 ①REQUIRED

如果存在一个事务,则支持当前事务,如果没有事务则开启一个新的事务。(默认事务)

这个意思就是insert方法之前没有事务,我就开启一个新的事务,到insert2的时候已经有了,就不会创建新的事务,还是用insert的那个事务.所以insert2成功之后到insert的时候有异常,事务回滚,全部回滚掉了.数据库一条数据都没有插入

@Transactional(propagation = Propagation.REQUIRED)
//@Transactional 默认不写
public int insert(Stu stu) {
     insert2(stu);
     stu.setStuId(GuoUtil.getUUID());
     System.out.println(1/0); //故意制造异常
     return stuMapper.insertSelective(stu);
}

REQUIRES_NEW

总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

这个意思就是insert方法之前没有事务,我就开启一个新的事务,到insert2的时候发现已经有事务了,所以吧insert的事务挂起,自己又开启一个新的事务,运行完insert2方法之后,提交保存到数据库. 再回到insert的时候发现异常,insert事务回滚,但不影响insert2的事务.所以此时数据库有一条数据

@Transactional(propagation = Propagation.REQUIRES_NEW)

@Transactional不生效的情况

  1. @Transactional  在private 方法是不生效
  2. 在同一个bean里,嵌套的public方法@Transactional 也不生效

注意一下不生效的情况: private方法加上去不报错,但是没效果;同一个类里面insert方法里面调用insert2方法,insert2方法的事务也是不生效的.

不搞不知道,一搞吓一跳!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值