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中的用户插入方法也回滚了。
相关推荐
:-)几秒前
idea配置maven国内镜像
java·ide·maven·intellij-idea
啊阿狸不会拉杆33 分钟前
《算法导论》第 27 章 - 多线程算法
java·jvm·c++·算法·图论
用户8029735654133 分钟前
【水平:编写简单的SpringCloud】用一篇文章精通SpringCloud-1
java
蔡俊锋1 小时前
Javar如何用RabbitMQ订单超时处理
java·python·rabbitmq·ruby
天天摸鱼的java工程师1 小时前
Snowflake 雪花算法优缺点(Java老司机实战总结)
java·后端·面试
Tapdata1 小时前
《实时分析市场报告 2025》上线 | 从批处理到实时洞察,2025 年全球实时分析市场全景解读
数据库
Miraitowa_cheems1 小时前
LeetCode算法日记 - Day 11: 寻找峰值、山脉数组的峰顶索引
java·算法·leetcode
海梨花2 小时前
【从零开始学习Redis】项目实战-黑马点评D2
java·数据库·redis·后端·缓存
共享家95272 小时前
linux-高级IO(上)
java·linux·服务器
橘子郡1232 小时前
观察者模式和发布订阅模式对比,Java示例
java