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中的用户插入方法也回滚了。
相关推荐
极限实验室5 分钟前
INFINI Labs 产品更新 | INFINI Console 1.29.6 发布 – 优化监控图表异常毛刺等
数据库·产品
先睡8 分钟前
优化MySQL查询
数据库·sql
一头生产的驴11 分钟前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao18 分钟前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc78721 分钟前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
小张是铁粉24 分钟前
oracle的内存架构学习
数据库·学习·oracle·架构
专注API从业者29 分钟前
构建淘宝评论监控系统:API 接口开发与实时数据采集教程
大数据·前端·数据库·oracle
藏在歌词里32 分钟前
数据库-元数据表
数据库
小乌龟不会飞2 小时前
Ubuntu 安装 etcd 与 etcd-cpp-apiv3
数据库·etcd
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展