Spring的7种事务传播行为分析实例(二)

接着上一篇讲的,确保数据库连接和操作没有问题之后,开始对事务传播行为进行测试,在浏览器中输入路径http://localhost:8080/user/save,来看一下测试结果:

从控制台中可以看到Hibernate打印出了一条insert语句,证明插入了一条数据,但是为什么doA()方法和doB()方法都执行了却只插入了一条数据呢?那插入的这条数据又是哪个方法里面的呢?我们先到数据库查询一下:

可以明显的看出,这条数据是doB()方法里面插入的,而doA()中插入的数据被回滚了,这是因为我们在doB()方法中加入ROPAGATION_REQUIRES_NEW传播行为,doB()创建了属于自己的事务,挂起了doA()中的事务,所以事务B提交了,而在doA()方法中加入的是ROPAGATION_REQUIRED传播行为,事务A因为执行异常,不会再创建新的事务,因此插入的数据被回滚了。

注意:在上面的实例中,我们没有把doB()方法放在UserController中,在doA()方法中直接调用doB()方法,而是放在了BusinessServiceImpl中,这是因为spring通过扫描所有含有注解的@Transactional的方法,使用aop形成事务增强advise。但是加入增强时是通过代理对象调用方法的形式加入的,如果将doB()方法放在doA()方法直接调用时,在调用doB()方法的时候是通过当前对象来调用doB()方法的,而不是通过代理来调用的doB()方法,这个时候doB()方法上加的事务注解就失效了不起作用。

如果我们将doB()方法做下修改,改为第一种传播行为ROPAGATION_REQUIRED:

再来看测试结果:

可以明显的看出,一条数据都没有插入到数据库中,这是为什么呢?因为这两个方法使用的都是第一种传播行为PROPAGATION_REQUIRED ,doB()方法被加入到doA()的事务中,doA()执行时抛出了异常,因为doB()和doA()同属于一个事务,则执行操作被一起回滚了。其实在doB()中我们不加入注解,也等同PROPAGATION_REQUIRED的效果,因为Spring中事务传播行为默认为PROPAGATION_REQUIRED方式,它也是我们最常用的一种方式。

接下来我们再来看看第五种传播行为PROPAGATION_NOT_SUPPORTED,我们同样修改doB()方法,将@Transactional注解中的propagation改为Propagation.NOT_SUPPORTED,再看测试结果:

结果和上面第一种方式一样,doB()方法成功插入了数据,而doA()方法中插入的数据被回滚了。这是因为传播行为PROPAGATION_NOT_SUPPORTED是doB()以非事务执行的,并且提交了。所以当doA()的事务被回滚时,doB()的操作没有被回滚。

其他的传播行为就不一一列举了,机制是差不多的。若大家还想更深入的了解事务传播行为,推荐给大家一篇文章,写的非常详细:https://segmentfault.com/a/1190000013341344

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值