@Transactional调用不生效问题及解决方案

2023-11-13

@Transactional调用不生效问题及解决方案

参考博文:
@Transactional的几种失效场景_勇往直前的小白的博客-CSDN博客
Spring事务回滚和异常类_huapro.vip的博客-CSDN博客
感谢以上博主的分享,致敬!

1、事务是什么


事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部都成功,要么一个都不做.

2、事务的四大特性


--原子性:整个事务中的所有操作,要么全部完成,要么全部都不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样.      
--一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏.      
--隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致.事务隔离分为不同级别,包括读未提交(Read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和串行化(Serializable).
--持久性:在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚.

3、@Transactional


@Transactional是spring中常用的注解之一,通常情况下我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception(运行时异常),就会发生rollback.

--作用
@Transactional 可以作用在接口、类、类方法:
作用于类: 当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息
作用于方法: 当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息
作用于接口: 不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效

--属性
@Transactional注有如下属性:
propagation: 代表事务的传播行为
isolation : 事务的隔离级别
timeout : 事务的超时时间,默认值为 -1.如果超过该时间限制但事务还没有完成,则自动回滚事务
readOnly : 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true
noRollbackFor: 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型

4、@Transactional失效场景

1、同一个类中方法调用(同一个类中,方法B有事务,方法A没有,在该类中方法A调用方法B,事务不生效)
2、@Transactional 应用在非 public 修饰的方法上
3、异常捕获后,没有抛出runtimeException异常
(事务是否执行取决于是否抛出runtime异常。如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。如果一定要写try-catch,需要在catch最后一行throw一个runtimeException,这样事务才会执行)
例如:
catch(ParseException e){
   throw new RuntimeException("抛出异常");
}
4、数据库引擎不支持事务。(仅InnoDB支持)
5、默认情况下,Spring会对Error或者RuntimeException异常进行事务回滚,
   其他继承自java.lang.Exception的异常:如IOException、TimeoutException等,不会回滚(如下图,绿色的是Spring会回滚的)
6、@Transactional 注解属性 propagation 设置错误,一定要设置成支持事务的,或者不设置(默认是Propagation.REQUIRED)

--同一个类中方法调用失效原因分析
Spring采用动态代理(AOP)实现对bean的管理和切片,它为我们的每个class生成一个代理对象.只有在代理对象之间进行调用时,可以触发切面逻辑。而在同一个class中,方法B调用方法A,调用的是原对象的方法,而不通过代理对象.所以Spring无法切到这次调用,也就无法通过注解保证事务性了。
也就是说,在同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用

请添加图片描述

5、解决方法

方法1、自己@Autowired自己
问题:可能会出现循环依赖的问题

方法2、将事务方法放到另一个类中(或者单独开启一层,取名“事务层”)进行调用,即符合了在对象之间调用的条件

方法3、获取本对象的代理对象,再进行调用

启动类中添加 @EnableAspectJAutoProxy(exposeProxy = true)
请添加图片描述

代码中使用AopContext.currentProxy()获取到当前代理类,强行通过代理类,激活事务切面
请添加图片描述

exposeProxy = true用于控制AOP框架公开代理,公开后才可以通过AopContext获取到当前代理类(默认情况下不会公开代理,因为会降低性能)
使用@EnableAspectJAutoProxy注解开启Spring对AspectJ的支持,表示开启AOP代理自动配置,表示使用cglib进行代理对象的生成

更多资料

@Transactional事务不生效的几种解决方案 - 知乎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@Transactional调用不生效问题及解决方案 的相关文章

随机推荐

  • codisQ&A

    Codis 是什么 Codis 是 Wandoujia Infrastructure Team 开发的一个分布式 Redis 服务 用户可以看成是一个无限内存的 Redis 服务 有动态扩 缩容的能力 对偏存储型的业务更实用 如果你需要 S
  • git中将某一分支代码完全覆盖另一分支

    如果需要将分支1的代码覆盖到分支2上 只需要如下操作 1 切换到分支2 git checkout 分支2 2 设置代码给远程的分支1 git reset hard origin 分支1 3 本地已覆盖 推送到远程分支上 git push f
  • 【Github】查看项目时可以清晰明了的看到项目的结构以及具体代码

    效果如下 Octotree通过左侧面板中的目录轻松浏览仓库的源代码 如下图 Octotree安装步骤 1 下载octotree 路径 https dl pconline com cn download 2561546 html 如果下载不成
  • 7-11 计算天数 (15 分)

    本题要求编写程序计算某年某月某日是该年中的第几天 输入格式 输入在一行中按照格式 yyyy mm dd 即 年 月 日 给出日期 注意 闰年的判别条件是该年年份能被4整除但不能被100整除 或者能被400整除 闰年的2月有29天 输出格式
  • 解决brew卡在Updating Homebrew...的正确姿势

    Updating的终端不要关 新开一个标签页 直接输入后续命令即可
  • Android 页面倒计时跳转 微博启动页为例

    首先创建项目 然后在右键再创一个empty avtivity xml布局中的图片自己去找然后复制进去 可复制进drawable中
  • 00 数组基础知识

    1 数组的存储方式 数组是存放在连续内存空间上的相同类型数据的集合 数组可以方便的通过下表索引的方式获取到下表下对应的数据 注意 数组的下标都是从0开始的 数组内存空间的地址是连续的 数组中存放的数据类型相同 正是因为数组的在内存空间的地址
  • 逆向爬虫07 requests进阶(反爬)

    逆向爬虫07 requests进阶 反爬 1 有些网站会在被访问时 检查客户端是否为浏览器 如果不是浏览器则拒绝访问 该问题可以通过在requests请求中 添加浏览器header参数 装成浏览器 import requests url h
  • BadImageFormatException,如果在安装32位oracle客户端组件的情况下以64位模式运行,将出现此问题

    今天开发人员发过来个问题 如题 现场是64位oracle 64位数据库主机 32 64位 具体不能确定 应用 64位应用中间件服务器 32位oracle客户端 这个问题按照字面来理解 就是安装了32位oracle客户端 但是试图以64位模式
  • Flask-SQLAlchemy插件

    Flask SQLALchemy插件 另外一个框架 叫Flask SQLAlchemy Flask SQLAlchemy是对SQLAlchemy进行了一个简单的封装 使得我们在flask中使用sqlalchemy更加的简单 可以通过 pip
  • 【RouterOS】利用ros搭建×××(PPTP)服务器要点

    关于拨号 与此对应的还有SiteToSite 的用途 我想不必多说 举几个例子 1 公司员工出差在外 需要收取公司内网的邮件 就需要 拨号进入公司内网收发邮件 2 网吧的技术人员在家休假时 需要远程维护网吧服务器 也需要 拨号进入网吧的网络
  • 随机森林原理及其用于分类问题的matlab实现

    随机森林 随机森林是多个决策树的集成学习 每个决策树用bagging的方法选数据集 并且在选择最佳属性划分的时候随机划分一些属性进行分类 比单个分类器效果更好 泛化能力更强 代码解释 1 用结构体的嵌套实现树的结构 2 makerandom
  • CSDN 不能复制或需关注才能查看代码

    解决csdn 不能复制问题 F12 不能复制代码 content views pre css user select text content views pre code css user select text 关注才能看代码 var
  • USB的传输,编码,数据格式,掌握usb的必备知识

    1 端点 位于USB设备或主机上的一个数据缓冲区 用来存放和发送USB的各种数据 每一个端点都有惟一的确定地址 有不同的传输特性 如输入端点 输出端点 配置端点 批量传输端点 2 帧 时间概念 在USB中 一帧就是1MS 它是一个独立的单元
  • d3dx9_43.dll如何修复

    你是否也和小编已经在运行一些应用程序或电脑游戏时会弹出d3dx9 43 dll文件丢失 小编在网上查询了此类文件丢失后的解决方案 并将其以图文的形式完成了整理 你只需要根据步骤完成操作即可解决这项问题 有一说一 莫名打不开电脑游戏是非常让人
  • Python语法检查——pyflakes

    Python 语法检查 pyflakes 安装 python m install pyflakes 使用 python m pyflakes xxx py
  • 终止代码 page_fault_in_nonpaged_area

    终止代码 page fault in nonpaged area 解决方法 电脑如果出现了 Page Fault In Nonpaged Area 错误 说明电脑的虚拟内存分页文件出现了问题 解决方法如下 第一步 用鼠标右键单击桌面上的 计
  • Spring Boot学习三:事务管理

    前面我们已经配置好了JPA 那么为了保证数据的一致性 我们就要用到事务控制 在springboot上使用事务其实很简单 就一个注解 Transactional 那么就来试试吧 首先写个方法 RequestMapping save Trans
  • makefile 自动生成头文件依赖关系

    在使用makefile 自动生成头文件依赖是 大家多半使用了下面这个方法 这个sed语句被称之为 上帝的符号 可读性不言而喻 PS CSDN这个排版怎么也搞不好 只能用图片了 gcc的 MMD 选项可以自动生成带有依赖规则的 d文件 为创建
  • @Transactional调用不生效问题及解决方案

    Transactional调用不生效问题及解决方案 参考博文 Transactional的几种失效场景 勇往直前的小白的博客 CSDN博客Spring事务回滚和异常类 huapro vip的博客 CSDN博客 感谢以上博主的分享 致敬 1