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中的用户插入方法也回滚了。
相关推荐
Python私教2 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
吾日三省吾码3 小时前
JVM 性能调优
java
弗拉唐4 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi774 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
BestandW1shEs5 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师5 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球5 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...5 小时前
表的操作(MySQL)
数据库·mysql·表的操作
哥谭居民00015 小时前
MySQL的权限管理机制--授权表
数据库