spring定义了7种事务传播机制:
1、REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED)
支持当前事务,如果没有事务会创建一个新的事务
2、SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS)
支持当前事务,如果没有事务的话以非事务方式执行
3、MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY)
支持当前事务,如果没有事务抛出异常
4、REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW)
创建一个新的事务并挂起当前事务
5、NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED)
以非事务方式执行,如果当前存在事务则将当前事务挂起
6、NEVER(TransactionDefinition.PROPAGATION_NEVER)
以非事务方式进行,如果存在事务则抛出异常
7、NESTED(TransactionDefinition.PROPAGATION_NESTED)
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
看文字介绍感觉还是比较难以理解,下面重点对比一下REQUIRED、REQUIRES_NEW、NESTED这三种事物传播机制的区别
区别对比:
1、REQUIRED(默认的传播机制):
如果当前没有事务,则新建事务
如果当前存在事务,则加入当前事务,合并成一个事务
method a(){
b();
c();
}
@Transactional(propagation = Propagation.REQUIRED)
method b(){
//插入一条数据B
insert(B);
}
@Transactional(propagation = Propagation.REQUIRED)
method c(){
//插入一条数据C
insert(C);
throw new Exception("抛一个异常");
}
说明:
执行方法a()时,由于当前没有事务,则新建了一个事务A。
执行方法b()时,由于当前存在事务A,则加入事务A,数据B插入成功,但插入数据B的事务A还未提交。
执行方法c()时,由于当前存在事务A,则加入事务A,数据C插入后抛异常,回滚事务A。
结果:数据B插入失败,数据C插入失败。
2、REQUIRES_NEW:
新建事务,如果当前存在事务,则把当前事务挂起
method a(){
b();
c();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
method b(){
insert(B);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
method c(){
//插入一条数据C
insert(C);
throw new Exception("抛一个异常");
}
说明:
执行方法a()时,由于当前没有事务,则新建了一个事务A
执行方法b()时,由于当前存在事务A,则把事务A挂起,新建一个事务B,数据B插入成功,事务B提交
执行方法c()时,由于当前存在事务A,则把事务A挂起,新建一个事务C,数据C插入成功后抛异常,事务C回滚,数据C插入失败后不会影响数据B
结果:数据B插入成功,数据C插入失败。
3、NESTED
如果当前没有事务,则新建事务
如果当前存在事务,则创建一个当前事务的子事务(嵌套事务),子事务不能单独提交,只能和父事务一起提交。
method a(){
b();
c();
}
@Transactional(propagation = Propagation.NESTED)
method b(){
insert(B);
}
@Transactional(propagation = Propagation.NESTED)
method c(){
//插入一条数据C
insert(C);
throw new Exception("抛一个异常");
}
说明:
执行方法a()时,由于当前没有事务,则新建了一个事务A
执行方法b()时,由于当前存在事务A,则创建一个当前事务的子事务AB,数据B插入成功,此时子事务还未提交,待父事务A提交时才会提交子事务AB
执行方法c()时,由于当前存在事务A,则创建一个当前事务的子事务AC,数据C插入后抛异常,子事务AC抛异常待回滚
提交父事务A,提交子事务AB,回滚子事务AC
结果:数据B插入成功,数据C插入失败。