Spring事务传播机制

回顾

在这里插入图片描述

之前我们学习了Spring如何进行事务的实现和运用,今天我们来学习Spring事务的传播机制

简单介绍

Spring事务的传播机制就是当存在多个事务的时候,且多个事务方法存在调用关系,事务是如何在这些方法中进行传播的

事务的传播机制有哪些

@Transactional注解支持事务传播机制的设置,通过propagation属性来指定传播行为,
以A方法调用B方法为例,A⽅法运⾏时, 会开启⼀个事务. 当A调⽤B时, B⽅法本⾝也有事务, 此时B⽅法运⾏时, 是加⼊A的事务, 还是创建⼀个新的事务呢(使用自己的事务)?这个就涉及到了事务的传播机制.
Spring事务传播有以下七种机制:

Propagation.REQUIRED

默认的事务传播级别. 如果A存在事务, 则B加⼊该事务. 如果A没有事务, 则创建⼀个新的事务(事务中包含AB).

Propagation.SUPPORTS

如果A存在事务, 则B加⼊该事务. 如果A没有事务, 则A,B以都以⾮事务的⽅式继续运⾏.

Propagation.MANDATORY

强制性. 如果A存在事务, 则B加⼊该事务. 如果A没有事务, 则抛出异常.

Propagation.REQUIRES_NEW

创建⼀个新的事务(B) 如果A存在事务, 则把A事务挂起. 也就是说不管A⽅法是否开启事务, Propagation.REQUIRES_NEW修饰的B⽅法都会新开启一个事务, 且开启的事务相互独⽴, 互不⼲扰,就算A用A的事务,B用B的事务,A没有就算了

Propagation.NOT_SUPPORTED

B以⾮事务⽅式运⾏, 如果A存在事务, 则把A事务挂起(不⽤).

Propagation.NEVER

以⾮事务⽅式运⾏, 如果A存在事务, 则抛出异常.

Propagation.NESTED

如果A存在事务, 则创建⼀个事务作为A事务的嵌套事务来运⾏. 如果A没有事务, 则该取值等价于PROPAGATION_REQUIRED

实例

上面其中机制,我们只需要重点掌握两个:
REQUIRED
REQUIRES_NEW

REQUIRED

@RestController
public class PropagationController {
   
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private LogInfoService logInfoService;
    @Transactional( propagation = Propagation.REQUIRED)
    @RequestMapping("/insertInfo")
    public void insertInfo(String userName,String password){
   
        userInfoService.insert(userName,password);
        logInfoService.insert(userName,"用户注册成功");
    }
}

@Service
public class LogInfoService {
   
    @Autowired
    private LogInfoMapper logInfoMapper;
    @Transactional( propagation = Propagation.REQUIRED)
    public Integer insert(String userName, String op) {
   
    	Integer i = 10/0;
        return logInfoMapper.insert(userName,op);
    }
}
@Service
public class UserInfoService {
   
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Transactional( propagation = Propagation.REQUIRED)
    public Integer insert(String userName, String password) {
   
        return userInfoMapper.insert(userName,password);
    }
}

运⾏程序,程序报错,发现数据库没有插⼊任何数据
流程描述:

  1. insertInfo⽅法开始事务
  2. ⽤⼾注册, 插⼊⼀条数据 (执⾏成功) (和insertInfo使⽤同⼀个事务)
  3. 记录操作⽇志, 插⼊⼀条数据(出现异常, 执⾏失败) (和insertInfo使⽤同⼀个事务)
  4. 因为步骤3出现异常, 事务回滚. 步骤2和3使⽤同⼀个事务 所以步骤2的数据也回滚了

REQUIRES_NEW

将上述代码中将上述UserService和LogService的传播机制改为 REQUIRES_NEW
运行程序,我们观察程序,可以看到,user_info中已经成功新增了一条数据,但是log_info中却并没有成功
这是因为REQUIRES_NEW的调用方与被调用着的事务是独立的,之间互不影响.

NEVER

将UserService中的事务传播机制改为NEVER
运行程序,程序报错,数据也没有插入成功,这是因为NEVER的调用方不能有事务,否则会报错,并回滚

NESTED

将UserService和LogService中的传播机制改为NESTED
运行程序,发现似乎和REQUIRED一样,但是当我们手动给LogService进行回滚,就会发现,日志表新增失败了,但是用户表注册成功了,也就是说,调用方的事务包含被调用者的事务,但是被调用者的事务也是一个独立的事务,因此可以实现局部回滚

REQUIRED和NESTED的区别

整个事务如果全部执⾏成功, ⼆者的结果是⼀样的
如果事务⼀部分执⾏成功, REQUIRED加⼊事务会导致整个事务全部回滚. NESTED嵌套事务可以实现局部回滚, 不会影响上⼀个⽅法中执⾏的结果

相关推荐

  1. Spring 事务事务传播机制

    2024-02-03 14:26:01       27 阅读
  2. 关于Spring @Transactional事务传播机制详解

    2024-02-03 14:26:01       34 阅读
  3. Spring 事务的种类 ? 传播机制 ?

    2024-02-03 14:26:01       22 阅读
  4. 简单讲讲spring事务传播机制

    2024-02-03 14:26:01       18 阅读
  5. Spring事务传播机制有哪些

    2024-02-03 14:26:01       16 阅读
  6. Spring Boot 事务传播机制详解

    2024-02-03 14:26:01       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-03 14:26:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-03 14:26:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-03 14:26:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-03 14:26:01       20 阅读

热门阅读

  1. 关于sql关键字及敏感数据脱敏

    2024-02-03 14:26:01       33 阅读
  2. 蓝桥杯客观题练习笔记

    2024-02-03 14:26:01       35 阅读
  3. C++设计模式之工厂模式

    2024-02-03 14:26:01       29 阅读
  4. Linux:使用grep和more索日志内容排查Bug

    2024-02-03 14:26:01       32 阅读
  5. C++之结构体

    2024-02-03 14:26:01       26 阅读
  6. kingbase配置SSL双向认证

    2024-02-03 14:26:01       30 阅读
  7. GMSSL之ZUC256算法

    2024-02-03 14:26:01       35 阅读