赞
踩
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。Propagation枚举则引用了这些类型,开发过程中我们一般直接用Propagation枚举。
- public enum Propagation {
- REQUIRED(0),
- SUPPORTS(1),
- MANDATORY(2),
- REQUIRES_NEW(3),
- NOT_SUPPORTED(4),
- NEVER(5),
- NESTED(6);
-
- private final int value;
-
- private Propagation(int value) {
- this.value = value;
- }
-
- public int value() {
- return this.value;
- }
- }

参考文档:Spring事务管理中的七种传播机制及示例讲解 | 程序员小羊
传播机制 | 解释 |
Propagation.NEVER | 非事务执行操作,存在事务,抛出异常 |
Propagation.MANDATORY | 使用当前事务,没有事务,抛出异常 |
代码案例:
- //controller
- @RestController
- @RequestMapping("/op")
- public class TestController {
-
- @Autowired
- private TestService testService;
-
- @GetMapping("/test1")
- public void test1() {
- testService.test1();
- }
-
- }
-
- //service
- public interface TestService2 extends BaseService<Test> {
-
- void test2();
-
- void test3();
- }
-
- @Service
- public class TestServiceImpl2 extends BaseServiceImpl<TestMapper, Test> implements TestService2 {
-
-
- @Override
- @Transactional(propagation = Propagation.NEVER, rollbackFor = Exception.class)
- public void test2() {
- System.out.println("test2 存在事务 NEVER");
- }
-
- @Override
- public void test3() {
- System.out.println("test3 没有事务");
- }
- }
-
-
- public interface TestService extends BaseService<Test> {
-
- int insert(Test test);
-
- int update(Test test);
-
-
- void test1();
-
- void test4();
- }
-
- @Service
- public class TestServiceImpl extends BaseServiceImpl<TestMapper, Test> implements TestService {
-
- @Autowired
- private TestService2 testService2;
-
- @Override
- public int insert(Test test) {
- return getBaseMapper().insert(test);
- }
-
- @Override
- public int update(Test test) {
- return getBaseMapper().updateById(test);
- }
-
- @Override
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
- public void test1() {
- System.out.println("test1 存在事务 REQUIRED");
- //如果在调用NEVER类型的时候,一定要用这种代理的方式,NEVER才会生效
- testService2.test2();
- }
-
- @Override
- @Transactional(propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
- public void test4() {
- System.out.println("test4 存在事务 MANDATORY");
- testService2.test3();
- }
- }

测试结果
Propagation.NEVER
Propagation.MANDATORY
传播机制 | 解释 |
Propagation.REQUIRED | 需要在事务中执行,外层有事务就加入,没有事务就自己创建一个事务 |
Propagation.REQUIRES_NEW | 需要在一个新的事务中执行,这个事务独立于外层的事务,互不影响 |
Propagation.REQUIRES_NEW案例
- @Override
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
- public void test5() {
- System.out.println("当前事务 REQUIRED ");
- Test test = new Test();
- test.setUserName("上海");
- test.setAddress("中国");
- getBaseMapper().insert(test);
- //test6用REQUIRES_NEW修饰,里面有异常,那么当前的事务也会回滚,如果test5有异常,test6不会受到影响
- testService2.test6();
- //当前事务进行回滚,test6内容会正常增加
- int i = 1/0;
- }
-
-
- @Override
- @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
- public void test6() {
- System.out.println("创建了一个新的事务");
- Test test = new Test();
- test.setUserName("广州");
- test.setAddress("中国");
- getBaseMapper().insert(test);
-
- }

注意点:
REQUIRES_NEW如果在内层,它里面的事务独立于外层的事务,外层事务如果发送异常回滚跟REQUIRES_NEW里面内容无关,如果REQUIRES_NEW里面内容回滚,那么外层的事务也会跟着回滚。
Propagation.REQUIRES_NEW测试结果
传播机制 | 解释 |
Propagation.SUPPORTS | 外层有事务就加入,如果没有事务,就以非事务方式执行 |
Propagation.NOT_SUPPORTED | 以非事务的方式执行,执行的时候,先将外层的事务挂起,允许外层有事务。 |
传播机制 | 解释 |
Propagation.NESTED | 嵌套事务,它是已经存在事务的真正子事务,嵌套事务开始执行时,会取得一个保存点(savepoint),如果这个嵌套事务失败,将会回滚导这个保存点(savepoint),而不是整个事务的回滚 |
- @Override
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
- public void test7() {
- System.out.println("当前事务 REQUIRED ");
- Test test = new Test();
- test.setUserName("上海");
- test.setAddress("中国");
- getBaseMapper().insert(test);
- //NESTED事务如果进行回滚,但是不会对它外层的事务造成影响
- try{
- testService2.test8();
- }catch (Exception e){
-
- }
- }
-
- @Override
- @Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class)
- public void test8() {
- System.out.println("创建了一个新的子事务");
- Test test = new Test();
- test.setUserName("广州");
- test.setAddress("中国");
- getBaseMapper().insert(test);
- int i = 1/0;
- }

状态 | REQUIRES_NEW(两个独立事务) | NESTED(B事务嵌套在A事务中) | REQUIRED同一个事务 |
A异常B正常 | A回滚,B正常提交 | A与B一起回滚 | A与B一起回滚 |
A正常B异常 | B先回滚,A正常提交 | B先回滚,A再正常提交 | A与B一起回滚 |
A正常B正常 | B先提交,A再提交 | A与B一起提交 | A与B一起提交 |
REQUIRED
REQUIRES_NEW
NESTED
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
- public void test7() {
- System.out.println("当前事务 REQUIRED ");
- Test test = new Test();
- test.setUserName("上海");
- test.setAddress("中国");
- getBaseMapper().insert(test);
- //NESTED事务如果进行回滚,但是不会对它外层的事务造成影响
- try{
- testService2.test8();
- }catch (Exception e){
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。