@Transactional注解的注意事项

知识点1.事务的传播机制  默认是REQUIRED,意思是内嵌方法如果也用了@Transactional注解,则与外层事务方法共用一个事务。即同一个事务。

外层方法methodA内嵌调用了 studuentService的methodA()方法

Studentservice的方法定义如下:

StuService.methodA()执行结果:全部插入失败,事务回滚。

原因:共用一个事务,该事务在StudentService 类的methodA中抛空指针异常时被打上回滚标记,注定会被rollback,即使在外层事务方法中对异常进行了捕获处理,事务依然会被回滚。

 

变种验证1:去掉StuService类的methodA事务注解,保留StudentService类的methodA事务注解。

 

StuService.methodA()执行结果:张三 40 这条数据插入成功,李四 50插入失败。

原因:外层方法弃用事务后,sql正常提交。内嵌方法使用了事务注解,事务回滚。

变种验证2:两个类的methodA都加事务注解,并且将StudentService methodA事务传播机制改为 REQUIRES_NEW,这样StuService 和 StudentService methodA()方法将使用两个独立的事务.

如图:

StuService.methodA()执行结果:张三 40 这条数据插入成功,李四 50插入失败。

原因:两个事务相互独立,外层方法对异常进行了捕获处理,不会回滚。内层事务有异常,会回滚。

-------------------------

知识点2:@Transactional注解默认只回滚 RuntimeException,不回滚IOException.

例:StudentService类和StuService 类的 methodB() 都带有事务注解@Transactional,且方法没有任何对异常的捕获处理。

 

 

StuService.methodB()执行结果:全部插入成功。

原因:@Transactional注解默认只回滚 RuntimeException,忽略了 IOException

变种验证:将两个Service的methodB()方法上的注解改为

@Transactional(rollbackFor = Exception.class)

 

 StuService.methodB()执行结果:全部插入失败。

原因:事务对IOException做出了反应,作了回滚标记,事务最终回滚。

变种验证:去掉StuService methodB上的事务注解,弃用事务。StudentService methodB保留@Transactional(rollbackFor = Exception.class)

结果:StudentService methodB 事务回滚,插入失败。 而外层因为弃用了事务,插入成功。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值