Spring事务传播机制

在上篇文章中,小编带领大家了解了Spring事务:Spring事务-CSDN博客,那么,本篇文章将会带领大家深入了解:Spring事务传播机制,感兴趣的各位老铁,欢迎深入探讨!!

事务传播机制是什么??

Spring事务传播机制定义了多个包含事务的方法,相互调用时,事务是如何在这些方法间进行传递的!

为什么需要事务传播机制??

事务隔离级别是保证多个并发事务执行的可控性(稳定性)的,而事务传播机制是保证一个事务在多个调用方法间可控性(可靠性)的。如:像新馆病毒一样,他有不同的隔离方式(酒店隔离,居家隔离等)都是为列保证疫情可控,然而在每个人的隔离过程中,会有很多个执行的环节:比如:酒店隔离需要负责人员运送,物品运送,消杀原生活区域,定时核酸检和定时送餐等很多环节,而事务传播机制就是保证一个事务在传递过程中是可靠性的,回到本身案列中就是保证每个人在隔离的过程中可控的

事务传播机制解决的是一个事务在多个节点(方法)中的传递问题:

事务传播机制有哪些??

有以下7种:

  1. Propagation.REQUIRED:默认的事务传播级别,他表示如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。
  2. Propagation.SUPPORTS:如果当前存在事务则加入该事务,如果当前没有事务,则以非事务的方式继续运行。
  3. Propagation.MANDATORY(mandatory强制性):如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常。
  4. Propagation.REQUIRES_NEW:表示创建一个新的事务,如果当前存在事务,则把当前事务挂起,也就是说,不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会开启自己的事务,且开启的事务相互独立,互不干扰。
  5. Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  6. Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
  7. Propagation.NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行,如果当前没有事务,该取值等价于Propagation.REQUIRED

上述内容说白了,其实可以分为三大部分:

|-------------------------------------------------------|---------------------------------------------|------------------------------------------------------------------|
| 支持当前事务 | 不支持当前事务 | NESTED嵌套事务 |
| REQUIRED(需要有):如果当前方法没有事务,新建一个事务,如果已经存在一个事务,则加入当这个事务中。 | REQUIRES_NEW:新建事务执行,如果当前存在事务,则把当前事务挂起。 | NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则执行与Propagation.REQUIRED类似的操作 |
| SUPPORTS(可以有):支持当前事务;如果当前没有事务,就以非事务方式运行。 | NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 | |
| MANDATORY(强制有):使用当前事务;如果当前没有事务,则抛出异常。 | NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 | |

以情侣关系来列举以上分类:(该图片来自于网络:若有侵权,请联系小编删

Spring事务传播机制使用和各种场景演示:

1.支持当前事务(REQUIRED)

以下代码实现中,先开始事务先成功插入一条用户数据,然后在执行日志保存,而在日志报错是发生了异常,观察propagation=Propagation.REQUIRED的执行结果;

复制代码
@RestController
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private LogService logService;

    @RequestMapping("/save")
    @Transactional(propagation = Propagation.REQUIRED)
    public Object save(User user){
        //插入用户操作
        userService.save(user);
        //插入日志
        logService.saveLog("用户插入:"+user.getName());
        return true;
    }
}

UserService方法;

复制代码
@Service
public class UserService {
    @Resource
    private UserMapper userMapper;

    @Transactional(propagation = Propagation.REQUIRED)
    public int save(User user){
        System.out.println("执行save方法");
        return userMapper.save(user);
    }
}

LogService方法:

复制代码
@Service
public class LogService {
    @Resource
    private LogManager logManager;

    @Transactional(propagation = Propagation.REQUIRED)
    public int saveLog(String content){
        //出现异常
        int i=10/0;
        return logManager.saveLog(content);
    }

}

当然,对于上述程序的运行结果:程序报错,数据库没有插入任何数据。

执行流程描述:

  1. UserService中的保存方法正常执行完成。
  2. LogService保存日志程序报错,因为使用的是Controller中的事务,所以整个事务回滚。
  3. 数据库中没有插入任何数据,也就是步骤1中的用户插入方法也回滚了。
相关推荐
@淡 定4 分钟前
线程安全的日期格式化:避免 SimpleDateFormat 并发问题
java
qq_12498707535 分钟前
基于springboot框架的小型饮料销售管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·spring·毕业设计
Warren989 分钟前
datagrip新建oracle连接教程
数据库·windows·云原生·oracle·容器·kubernetes·django
焦糖玛奇朵婷10 分钟前
扭蛋机小程序:线上扭蛋机模式发展新形势[特殊字符]
大数据·数据库·程序人生·小程序·软件需求
YMatrix 官方技术社区23 分钟前
YMatrix 高可用详解:3 种镜像策略在节点宕机时表现有何不同?
运维·数据库·数据仓库·ai·数据库开发·数据库架构·ymatrix
嘟嘟w25 分钟前
SQL注入是什么
数据库·sql·oracle
摇滚侠26 分钟前
Redis 零基础到进阶,Redis 主从复制,笔记55-62
数据库·redis·笔记
surtr127 分钟前
数据库基础(数据库原理和应用)
数据库·sql·mysql·oracle·database
CodeAmaz28 分钟前
JVM一次完整GC流程详解
java·jvm·gc流程
张人玉31 分钟前
c# DataSet 类
数据库·c#·dataset