说起spring的事务传播机制,很多人知道,也了解过,但是真正理解的可能真的不多,我们今天就来详细的spring默认的事务传播机制Propagation.REQUIRED,如果其他事务传播机制你似懂非懂或者记不住的话,不要紧,但一定要记住spring默认的事务传播机制因为在大部分的情况下很少有程序员去修改或者设置spring默认的传播机制,如果这个你的搞不懂的话那你开发的东西就很难让领导放心了
spring在TransactionDefinition接口中规定了7种类型的事务传播行为。事务传播行为是Spring框架独有的事务增强特性,它不属于的事务实际提供方数据库的行为。
PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择,也是spring默认事务传播机制
前期准备工作:
数据库中创建user1表
创建user2表
项目中创建user1实体类
创建user2实体类
创建user1的Mapper
创建user2的Mapper
创建user1Service,这里注意addRequired方法propagation设置的值为REQUIED,因为是默认的,所以也可以不显性设置
创建user2Service,注意addRequiredException方法,主动的抛出了一个运行时异常,程序跑到这里之后一定会报异常
下面开始测试,分别测试不同的情况
1.1 场景一
此场景外围方法没有开启事务。
验证方法1:notransaction_exception_required_required方法上没有开启事务,
验证方法2:notransaction_required_required_exception方法没有开启事务
结果总结:
验证方法1:张三,李四都插入到数据库中。外围方法未开启事务,插入“张三”、“李四”方法在自己的事务中独立运行,外围方法异常不影响内部插入“张三”、“李四”方法独立的事务。
验证方法2:张三插入数据库中,李四未插入。外围方法没有事务,插入“张三”、“李四”方法都在自己的事务中独立运行,所以插入“李四”方法抛出异常只会回滚插入“李四”方法,插入“张三”方法不受影响。
结论:通过这两个方法我们证明了在外围方法未开启事务的情况下Propagation.REQUIRED修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。
1.2 场景二
外围方法开启事务,这个是使用率比较高的场景。
结果:“张三”、“李四”均未插入。外围方法开启事务,内部方法加入外围方法事务,外围方法回滚,内部方法也要回滚。
结果:“张三”、“李四”均未插入。外围方法开启事务,内部方法加入外围方法事务,内部方法抛出异常回滚,外围方法感知异常致使整体事务回滚。
结果:“张三”、“李四”均未插入。外围方法开启事务,内部方法加入外围方法事务,内部方法抛出异常回滚,即使方法被catch不被外围方法感知,整个事务依然回滚。
这个结果估计有人会意想不到,想着已经try,catch了应该不会回滚,但事实就是回滚了,大家可以测试一下。
结论:以上试验结果我们证明在外围方法开启事务的情况下Propagation.REQUIRED修饰的内部方法会加入到外围方法的事务中,所有Propagation.REQUIRED修饰的内部方法和外围方法均属于同一事务,只要一个方法回滚,整个事务均回滚。