基于@Transactional注解操作事务的传播行为
一.@Transactional中七种事务传播行为
事务传播行为 | 效果 |
---|---|
REQUIRED:(必须) | 如果以前有事务,就和之前的事务共用一个事务,没有就创建一个事务。 |
REQUIRES_NEW(新的事务) | 创建一个新的事务,如果以前有事务,暂停前面的事务,也就是说总是用新事务。 |
SUPPORTS(支持) | 之前有事务,就和之前事务共用的方式运行,没有事务也可以。 |
MANDATORY(强制) | 一定要有事务,如果没事务就报错。 |
NOT_SUPPORTED(不支持) | 不支持在事务内运行,如果已经有事务了,就挂起当前存在的事务。 |
NEVER(从不使用) | 不支持在事务内运行,如果已经有事务了,抛异常。 |
NESTED | 开启一个子事务(MySQL不支持),需要支持还原点功能的数据库才行 |
@Transactional默认的传播行为是REQUIRED,且一般情况下只用REQUIRED和REQUIRES_NEW,其他了解即可
@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.REQUIRES_NEW)
二.为什么要控制事务的传播行为
一些人在需要使用事务控制的方法上,直接加上@Transactional注解,保证方法中一步出错,全部回滚,当然,一些情况下这样操作也没有问题。但一些业务场景下,不需要全部回滚,如保存一件商品需要:
- 保存该商品基本信息.
- 保存库存数量。
- 保存商品的参数值。
- 保存商品满减条件。
这样的场景下只需控制商品的基本信息和库存等核心数据保存成功后不管后面执行情况都不再回滚。
三.事务的传播行为使用例子
@Transactional
public void add(){
A(); //事务:REQUIRED
B(); //事务:REQUIRES_NEW
Mapper.xxx();
int i =