Spring事务注意事项 以及 遇到的坑
原创参考:
https://www.cnblogs.com/yougewe/p/7466677.html (Spring,为内部方法新起一个事务,此处应有坑。)
https://blog.csdn.net/bntx2jsqfehy7/article/details/79040349 (面试必备技能:JDK动态代理给Spring事务埋下的坑!)
spring 事务注意事项:
注意:
@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。
默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。因为动态代理的原因。
在 SPRING 中一共定义了六种事务传播属性 PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 最容易弄混淆的其实是PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全
commited 或 rolled back 而不依赖于外部事务,它拥有自己的隔离范围, 自己的锁, 等等.
当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.
PROPAGATION_REQUIRES_NEW常用于日志记录,或者交易失败仍需要留痕 另一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正
的子事务. 潜套事务开始执行时, 它将取得一个 savepoint.
如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分,
只有外部事务结束后它才会被提交.
由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于,
PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED
则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit,
这个规则同样适用于 roll back. 几个例子理解REQUIRED、REQUIRES_NEW、NESTED 的使用注意事项(TRY...CATCH配合使用) 1、REQUIRED的使用注意项 1.1 REQUIRED保证其处理过程同一个事务,如果调用的同一个类的配置的REQUIRED的方法,且此方法存在TRY CATCH
代码块, 如果此代码块出现异常,程序可以继续执行。 1.2 但如果调用的其他类的配置REQUIRED方法,且TRY CATCH住,则全部的提交全部回滚,且报出异常:
Transaction rolled back because it has been marked as rollback-only
因为事务报出异常后要全部回滚,包括父类的调用。 1.3 如果service中包含多个dao的方法,其都属于同一个事务,其中报错全部回滚,try catch住不影响程序代码的继续执行. class A{
//PROPAGATION_REQUIRED
void methodA() {
try{
methodB(); //可以继续执行,因为是同一个类
}catch(Exception ex){
ex.printStrace();
} try{
methodC(); //报错Transaction rolled back because it has been marked as rollback-only
//因为回滚整个事务,不能用try catch住.当然通过不会try catch一个事务的部分代码
}catch(Exception ex){
ex.printStrace();
}
} //PROPAGATION_REQUIRED
void methodB() { }
} class B{ //PROPAGATION_REQUIRED
void methodC() { }
} 2、NESTED的具体用途如下:
在此方法出现异常时,通过TRY CATCH 代码块包含住, 继续往下执行或者执行CATCH中的处理.
此点REUQIRED做不到, REQUIRED_NEW能做到, 但它是单独的事务,不与父类一块提交的。 ServiceA {
/** * 事务属性配置为 PROPAGATION_REQUIRED */ void methodA() { try { //savepoint ServiceB.methodB(); //PROPAGATION_NESTED 级别 } catch (SomeException) { // 执行其他业务, 如 ServiceC.methodC();
}}}
Spring事务注意事项 以及 遇到的坑的更多相关文章
- Spring事务传播行为中可能的坑点
一.简介 Spring事务配置及相关说明详见:https://www.cnblogs.com/eric-fang/p/11052304.html.这里说明spring事务的几点注意: 1.默认只会检查 ...
- Spring 事务注意事项
使用事务注意事项 1,事务是程序运行如果没有错误,会自动提交事物,如果程序运行发生异常,则会自动回滚. 如果使用了try捕获异常时.一定要在catch里面手动回滚. 事务手动回滚代码 Transact ...
- required_new spring事务传播行为无效碰到的坑!
在测试事务传播行为的时候,因为用了同一个service中的方法测试,所以不管怎么设置都无效了: 原因是aop动态代理只会拦截一次执行方法,第二个方法是照搬的,只要调用其他service中的事务方法,传 ...
- JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- 记一次 Spring 事务配置踩坑记
记一次 Spring 事务配置踩坑记 问题描述:(SpringBoot + MyBatisPlus) 业务逻辑伪代码如下.理论上,插入数据 t1 后,xxService.getXxx() 方法的查询条 ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- [转]@Transactional spring 配置事务 注意事项
@Transactional spring 配置事务 注意事项 [@more@] @Transactional spring 配置事务 注意事项 1. 在需要事务管理的地方加@Transactiona ...
- 聊聊spring事务失效的12种场景,太坑了
前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...
- 聊聊Spring事务控制策略以及@Transactional失效问题避坑
大家好,又见面了. 在大部分涉及到数据库操作的项目里面,事务控制.事务处理都是一个无法回避的问题.比如,需要对SQL执行过程进行事务的控制与处理的时候,其整体的处理流程会是如下的示意: 首先是要开启事 ...
- spring事务配置的坑
基于 <tx> 命名空间的声明式事务管理 前面两种声明式事务配置方式奠定了 Spring 声明式事务管理的基石.在此基础上,Spring 2.x 引入了 <tx> 命名空间,结 ...
随机推荐
- Windows环境同时安装多个版本的Python解释器(python2和python3)
https://blog.csdn.net/qq_21583139/article/details/125881382 出现问题: 更新pip 操作后出现,pip报错,应该是升级到最新pip版本然后和 ...
- Java面向对象之内部类
内部类 内部类:在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对于B类来说就是外部类了. 1.成员内部类 2.静态内部类 3.局部内部类 4.匿名内部 ...
- Linux 部署apache2.4
apache httpd-2.4.46.tar.gz部署环境 Linux6.5 依赖包: apr-1.6.3.tar.gz apr-util-1.5.2.tar.gz 先部署apr 1.tar -xf ...
- SpringBoot容器化的多环境配置
SpringBoot容器化的多环境配置 部署通常会有多个环境,如"dev"/"test"/"prod"等环境 容器化部署通常使用环境变量,而 ...
- JAVA诞生历史【转载】
一.计算机语言的发展史 1.第一代语言(只有机器能读懂,人根本读不懂) 纯机器语言 2.第二代语言(机器能读懂,人可以读懂,但是很难懂) 汇编语言(符号语言) 3.第三代语言(机器能读懂,也非常便于人 ...
- java后台接收参数为枚举,postman的json如何传入
使用postman测试接口,其中一个参数为枚举类型,如何传入参数? 1 枚举类型: public enum UserCourseOrderSourceType{ USER_BUY(1,"用户 ...
- CCF 201903-1 小中大
#include <iostream> #include <bits/stdc++.h> #include <string> using namespace std ...
- vue3 门户网站搭建1-路由
从 0 到 1搭建门户网站,记录一下. 因为需求不大,所以比较简单,门户和后台管理直接一个项目出来,路由配置则想的是: 1.门户,用 /portal 标识 2.后台管理,用 /admin 标识 3. ...
- oracle数据库安装出现的问题
根据相关安装教程,安装好oracle后,使用plsql连接时,不能成功连接时: 1.检查相关的环境变量等是否配置正确 2.认真看清楚 oracle客户端的相关配置 3.出现这个问题(我的是没有选择当前 ...
- 重新安装office原版本没卸载干净
先在设置--卸载界面确保已经卸载 在键盘上按"win+R",在运行窗口里面输入"regedit",回车 ,进入注册表编辑器 找到products 删除与offi ...