Spring的7种事务传播方式
Spring事务传播行为体现在某个service方法调用另一个service方法,事务该如何进行下去。
Spring支持7中事务传播方式,在Propagation类中可以看到,如下:
REQUIRED(0), SUPPORTS(1), MANDATORY(2), REQUIRES_NEW(3), NOT_SUPPORTED(4), NEVER(5), NESTED(6);
使用方式就是在service方法上加入Transational注解,例如:
@Transactional(propagation = Propagation.NOT_SUPPORTED)
下面逐个介绍下这7中事务传播方式:
1. REQUIRED:
Spring的默认事务传播方式。从字面意思看,它表示此枚举修饰的service方法必须运行在一个事务中,如果当前存在一个事务(比如其他有事务的service方法调用此方法),则运行在当前事务中,否则开启一个新的事务。
示例代码如下:
注意:这里methodA调用methodB必须要用Spring的代理方式,即用testService.methodB()方式调用,如果只是method()方式调用则相当于this.methodB()在本对象中调用,事务不起作用的,一定要是Spring的AOP代理。@Lazy注解是为了防止启动的时候出现循环依赖报错,采用懒加载方式注入Bean。
下面示例中,methodA调用methodB的时候,会先开启一个事务,methodB中会使用methodA这个事务,和methodA一起提交或回滚。
@Service
public class TestServiceImpl implements TestService {@Resource @Lazyprivate TestService testService;@Transactional@Overridepublic void methodA() {testService.methodB();System.out.println("CRUD operation in methodA...");}@Transactional@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");}
}
2. SUPPORTS:
从字面意思看,它是支持的意思,也就是有事务我也支持,没有也行。
即:调用此方法时如果有一个事务,那么就在当前事务中执行,和当前事务一起提交或回滚。如果当前没有事务,那么就不开启事务,在无事务环境中执行。
下面示例代码中,methodB是SUPPORTS事务传播方式,methodB有没有事务取决于调用它的methodA。可以看到此时methodA是有一个事务的,所以methodB会在methodA这个事务中一起提交或回滚。
@Service
public class TestServiceImpl implements TestService {@Resource @Lazyprivate TestService testService;@Transactional@Overridepublic void methodA() {testService.methodB();System.out.println("CRUD operation in methodA...");}@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");}
}
3. MANDATORY:
字面意思:强制。
没错,就是一定要在事务中执行,否则就会抛异常。
如下面的代码,如果直接调用methodB,由于当前没有事务,会抛出一个IllegalTransactionStateException异常。如果是在methodA中调用methodB,由于methodA开启了一个事务,所以methodB会在methodA的事务中执行,不会报错。
@Service
public class TestServiceImpl implements TestService {@Resource @Lazyprivate TestService testService;@Transactional@Overridepublic void methodA() {testService.methodB();System.out.println("CRUD operation in methodA...");}@Transactional(propagation = Propagation.MANDATORY)@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");}
}
4. REQUIRES_NEW:
字面意思:开启一个新的事务。
这个事务传播方式会挂起当前事务,开启一个新的事务,方法会在新的事务中执行并提交,提交完之后,挂起的事务继续往下走。
如下代码,methodA调用methodB的时候,当前事务会被挂起,然后在methodB中会开启一个新的事务,methodB执行完并且事务提交后,methodA的事务继续执行。methodB回滚不影响methodA,methodA回滚也不影响methodB。
@Transactional@Overridepublic void methodA() {testService.methodB();System.out.println("CRUD operation in methodA...");}@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");}
5. NOT_SUPPORTED:
字面意思:不支持事务。
用该枚举修饰的方法一定会运行在非事务环境中,即使调用此方法时有一个事务,也会将该事务挂起。我们通常将这种方式应用于强制要求非事务的方法中,例如我们现在要将批量数据去集成第三方接口然后更新状态到DB,不能说某一个数据出错就导致所有数据状态都回滚,那样的话,已经成功集成过第三方接口的数据就又得重新去集成了,会造成重复调用,导致第三方系统中的数据混乱。
如下代码,methodA有一个事务,当它调用methodB时,事务会被挂起,然后methodB中的CRUD操作不会在事务中执行,会立即提交到数据库。methodB执行完之后,methodA的事务继续进行,methodA的回滚不影响methodB。
@Transactional@Overridepublic void methodA() {testService.methodB();System.out.println("CRUD operation in methodA...");}@Transactional(propagation = Propagation.NOT_SUPPORTED)@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");}
6. NEVER:
字面意思:永远也不在事务中运行。
该枚举修饰的方法一旦在事务环境中就会抛异常。
7. NESTED:
字面意思:嵌套事务。
这种传播方式稍微有点复杂,目前各种厂商对它的支持可能存在差异,需要看具体的事务管理实现方式。
用此枚举修饰的方法,当外部有事务的时候,会在里面嵌套一个事务,里面的事务回滚不会影响外部事务,但外部事务出错回滚会将里面的也一起回滚。
如下methodB会在methodA的事务里面再嵌套一个事务,当methodA事务提交,methodB也会跟着一起提交,当methodA出错回滚,会把methodB也一起回滚。当methodB出错回滚,不会影响methodA的事务,事务会回退到调用methodB前的节点,然后继续处理后续的步骤。
@Transactional@Overridepublic void methodA() {System.out.println("CRUD operation in methodA before...");//保存当前状态,开启嵌套事务try {testService.methodB();} catch (Exception e) {e.printStackTrace();}//methodB回滚后不影响methodA事务继续进行System.out.println("CRUD operation in methodA...");}@Transactional(propagation = Propagation.NESTED)@Overridepublic void methodB() {System.out.println("CRUD operation in methodB...");throw new RuntimeException("methodB rollback");}
Spring的7种事务传播方式相关推荐
- Spring(1) Spring的7种事务传播行为
目录 1.7种事务传播行为 2.事务使用示例 3.REQUIRES_NEW 事务传播行为使用示例 3.1 事务传播图 3.2 TUserAServiceImpl.java 3.3 TUserBServ ...
- Spring的七种事务传播行为
一.什么是事务传播行为? 事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行. 例如:methodA方法调用methodB方 ...
- Spring的7种事务传播机制
前言 什么是事务? 事务就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元.对数据库的增删改查操作 传播机制是什么? 当A调 ...
- Spring的7种事务传播行为类型
1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置. 2.PROPAGATION_SUPPORTS:支持当前事务,如 ...
- Spring的七种事务传播行为,通俗易懂,绝不笼统,可以背诵,应付面试
文章目录 什么是事务传播行为 PROPAGATION(propagation)_REQUIRED(required) PROPAGATION_NESTED(nested) PROPAGATION_RE ...
- Spring中七种事务传播行为
事务的传播行为,默认值为 Propagation.REQUIRED.可手动指定事务传播行为,如下: 1.Propagation.REQUIRED 1)若嵌套在事务中,则加入该事务. 2)若没有嵌套在事 ...
- 简介表格让你牢牢记住spring的7种事务传播机制
事务行为 说明 Propagation_Required 支持当前事务,如果当前没有事务则新建事务(默认) Propagation_Requred_New 新建事务,如果当前存在事务则把当前事务挂起 ...
- spring 七种事务传播行为
spring事务传播行为详解 一.什么是事务传播行为? 二.Spring中七种事务传播行为 三.REQUIRED,REQUIRES_NEW,NESTED异同 四.三种Transactional不回滚问 ...
- Spring七种事务传播行为
事务传播行为 "事务传播行为"描述的是:当一个事务方法被另一个方法调用时,该事务方法如何进行? 是创建新事务?丢弃事务?还是加入到已存在的事务呢? 针对这些情况,Spring框架定 ...
最新文章
- “脑补”的科学依据:眼前的黑不是黑,靠得是你的大脑
- centos输入正确的账号和密码登陆不进去
- mysql查询各科前3_MySQL 查询各科前三的数据
- 第五节:EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope)
- 竟然被尤雨溪点赞了:我给Vue生态贡献代码的这一年
- qtabwidget放大_Qt自定义弹窗屏蔽父窗口(QWidget设置setWindowModality(Qt::ApplicationModal);以后再show)...
- CDLL和WinDLL的区别
- 通过SQL发送邮件,SQL发送Email(转)
- 终端中出现While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/pod错误的修改方法...
- php -- php数组相关函数
- 共轭梯度法的简单直观理解
- 关于来料检验中多退货的问题
- 开源的在线视频点播系统,值得分享!
- android与后台交互,Android客户端与服务端交互
- Linux下Teamviewer安装、设置及开机启动
- U盘启动BIOS设置
- 二十九、K8s最小服务漏洞3-gVisor沙箱
- js实现拼图游戏(数字版本与图片版本)
- 职业与生活规划是否必要?回答因人而异。但规划至少会给人带来以下好处。
- Docker实现SpringBoot项目的快速构建(二)