在上篇文章中,小编带领大家了解了Spring事务:Spring事务-CSDN博客,那么,本篇文章将会带领大家深入了解:Spring事务传播机制,感兴趣的各位老铁,欢迎深入探讨!!
事务传播机制是什么??
Spring事务传播机制定义了多个包含事务的方法,相互调用时,事务是如何在这些方法间进行传递的!
为什么需要事务传播机制??
事务隔离级别是保证多个并发事务执行的可控性(稳定性)的,而事务传播机制是保证一个事务在多个调用方法间可控性(可靠性)的。如:像新馆病毒一样,他有不同的隔离方式(酒店隔离,居家隔离等)都是为列保证疫情可控,然而在每个人的隔离过程中,会有很多个执行的环节:比如:酒店隔离需要负责人员运送,物品运送,消杀原生活区域,定时核酸检和定时送餐等很多环节,而事务传播机制就是保证一个事务在传递过程中是可靠性的,回到本身案列中就是保证每个人在隔离的过程中可控的
事务传播机制解决的是一个事务在多个节点(方法)中的传递问题:
事务传播机制有哪些??
有以下7种:
- Propagation.REQUIRED:默认的事务传播级别,他表示如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务。
- Propagation.SUPPORTS:如果当前存在事务则加入该事务,如果当前没有事务,则以非事务的方式继续运行。
- Propagation.MANDATORY(mandatory强制性):如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常。
- Propagation.REQUIRES_NEW:表示创建一个新的事务,如果当前存在事务,则把当前事务挂起,也就是说,不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会开启自己的事务,且开启的事务相互独立,互不干扰。
- Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
- 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);
}
}
当然,对于上述程序的运行结果:程序报错,数据库没有插入任何数据。
执行流程描述:
- UserService中的保存方法正常执行完成。
- LogService保存日志程序报错,因为使用的是Controller中的事务,所以整个事务回滚。
- 数据库中没有插入任何数据,也就是步骤1中的用户插入方法也回滚了。