事务注解@Transactional

news/2025/3/26 17:24:07/文章来源:https://www.cnblogs.com/jock766/p/18790089

目录


1、属性介绍


2、传播机制

  • 准备例子

  • 总结


3、原理

4、失效场景


一、属性介绍

1、isolation 属性

事务的隔离级别,默认值为 Isolation.DEFAULT。可选的值有:

  • Isolation.DEFAULT:使用底层数据库默认的隔离级别

  • Isolation.READ_UNCOMMITTED:读取未提交数据(会出现脏读,不可重复读、幻读)基本不使用

  • Isolation.READ_COMMITTED:读取已提交数据(会出现不可重复读和幻读)

  • Isolation.REPEATABLE_READ:可重复读(会出现幻读)

  • Isolation.SERIALIZABLE:串行化


2、timeout 属性

事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务


3、readOnly 属性

指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true


4、rollbackFor 属性

用于指定能够触发事务回滚的异常类型,可以指定多个异常类型


5、noRollbackFor 属性

抛出指定的异常类型,不会滚事务,也可以指定多个异常类型


7、propagation 属性

事务的传播行为,默认值为 Propagation.REQUIRED。可选的值有:

  • PROPAGATION.REQUIRED:如果当前没有事务,则创建一个新事务。如果当前存在事务,就加入该事务。该设置是最常用的设置

  • PROPAGATION.SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务。如果当前不存在事务,就以非事务执行

  • PROPAGATION.MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常

  • PROPAGATION.REQUIRE_NEW:创建新事务,无论当前存不存在事务,都创建新事务

  • PROPAGATION.NOT_SUPPORTED:以非事务方式执行操作,如果当前事务存在,就把当前事务挂起

  • PROPAGATION.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常

  • PROPAGATION.NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行


二、传播机制

属性上最值得关注的应该就是传播行为了,而在其中最难理解的就是这三个了,毕竟我们最关注的就是两个方法相互调用,发生了异常,是怎么回滚的是吧?其他的4个相对来说比较好理解

  • PROPAGATION.REQUIRED

  • PROPAGATION.REQUIRE_NEW

  • PROPAGATION.NESTED


1、准备例子

就是两个常规的Service,我们用A 去调用 B, A 方法固定采用REQUIRED ,B方法分别采用REQUIRED/REQUIRED_NEW/NESTED中的一种,然后在两个方法后分别加上异常看看回滚情况

  // A Service@Servicepublic class TestAImpl implements TestAService {@Resourceprivate TestBService testBService;@Resourceprivate TestMapper testMapper;@Override@Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED)public void testA() {testMapper.insertData(null,"testA");testBService.testB();}}// B  Service@Servicepublic class TestBImpl implements TestBService {@Resourceprivate TestAService testAService;@Resourceprivate TestMapper testMapper;@Override@Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED/REQUIRED_NEW/NESTED)public void testB() {testMapper.insertData(null,"testB");}}

首先我们要知道A调用B,如果B抛出异常在A中不捕获的话,那A是会正常回滚的,所以在测试REQUIRED_NEW/NESTED的时候记得在A中捕获B的异常


结果:

  • REQUIRED: 无论A异常还是B异常,双方都会回滚(注意不要捕获异常)

  • REQUIRED_NEW:因为B是独立的事务,所以A异常:A回滚,B不会回滚;B异常:B回滚,A不会回滚(前提是A要捕获B的异常,否则异常就会自己向上抛,也就影响了A)

  • NESTED:因为B是嵌套的事务,所以A异常,A和B都会回滚;B异常,B回滚,A不会回滚(前提是A要捕获B的异常,否则异常就会自己向上抛,也就影响了A)


2、总结

所以综合来看,最容易产生歧义的就是REQUIRED_NEW和NESTED,用这两者的时候记得要捕获B的异常,否则异常向上抛就没意义了,而这两个最大的区别就是一个是独立,一个是嵌套,独立则是父方法和子方法相互不影响,嵌套则是父方法影响子方法,而子方法不会影响父方法


三、原理


该注解的原理就是AOP,既然是AOP那就是动态代理,与AOP里面其他通知处理方法一样,该注解一样有一个拦截器处理方法,那就是TransactionInterceptor


源代码如下:

所以最终执行的的处理方法就是这个this.invokeWithinTransaction,该方法就是父类的方法,感兴趣的可以自己去看一下:


TransactionAspectSupport.invokeWithinTransaction

AOP最后执行的就是一个拦截器链条嘛。这个事务拦截器也会被放到链条里面去执行,有没有想过AOP里面的方法异常了,事务会回滚吗 ?


AOP通知方法异常会回滚吗 ?


正常情况下会回滚,拦截器链执行顺序与优先级有关,所以正常情况下这个事务会涵盖所有,但是你要是搞AOP的时候设置的优先级高过了事务的优先级,那事务就寄了,同理,你要是在AOP里面把异常给捕获处理了,那最外层感知不到事务自然也寄了


默认的排序如下:


三、失效场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904953.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nature | 整合空间转录组与GWAS数据绘制人复杂性状细胞空间图谱

这篇文章是2025年3月发表在《Nature》杂志上的一篇研究,标题为“Spatially resolved mapping of cells associated with human complex traits”。这篇文章通过开发一种名为gsMap的计算方法,整合高分辨率空间转录组(ST)数据与全基因组关联研究(GWAS)统计结果,实现对人类…

【笔记】力扣 102. 二叉树的层序遍历★

102. 二叉树的层序遍历 中等 提示 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1:输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例 2: 输入:root = [1] 输出:[[1]]示例 3: 输入:root = [] 输…

【Azure Container App】在消耗性的Container App Environmnet中无法查看当时正在使用多少CPU多少实例数的替代方案

问题描述 在Azure上使用Container App服务,创建服务环境的时候,选择类型为消耗型(Consumption)。但是,却无法查看当前所有应用中,具体使用了多少个 core (CPU), 目前有多少个实例呢? 如上图,上面的信息是 “-” 问题解答 因为在Container App Environment中所使用的Workl…

Redis短信登录场景

1、Redis短信登录场景 1.1、整体流程1.1、发送短信验证码 @Service @Slf4j public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic Result sendCode(String phone, HttpSession session) {// 1、校验手机号是否…

威联通TS-466C

威联通TS-466C CPU: Intel奔腾 银牌N6005 四核/ 四线程处理器,可高达 3.3 GHz 内存: 8G 3200MHz (可扩容到16G) 最大硬盘容量: 96T(22TB HDD x 4 + 4TB M.2 x 2)官网硬件参数: https://www.qnap.com.cn/zh-cn/product/ts-466c/specs/hardware 开箱安装硬盘 M2固态安装机械硬盘…

SvelteKit 最新中文文档教程(9)—— 部署静态站点与单页应用

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

FeedbackStream:8 分钟创建 AI 面试智能体;Moshi 开源图像理解实时语音模型 MoshiVis 丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看点的 活动 」,但内容仅代表编辑…

20234120 2024-2025-2 《Python程序设计》实验一报告

20234120 2024-2025-2 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2341 姓名: 李卓颖 学号:20234120 实验教师:王志强老师 实验日期:2025年3月22日 必修/选修:专业选修课 一、实验内容 (一)准备工作:1.安装Python和PyCharm:访问Python和PyCharm官…

day:28 postman——断言

一.postman 断言 1.断言再test中 状态码是否等于200: tests["Status code is 200"] = responseCode.code === 200; 断言响应时间小于200ms: tests["Response time is less than 200ms"] = responseTime < 200; 断言响应体包含内容: tests["Bod…

XDA论坛打不开的解决办法

开了梯子反而进不去,关掉全局代理 v2 可以添加两行 https://xdaforums.com/; https://www.xda-developers.com/;

国内首个HR智能体平台:开启人力资源管理智能化征程

在当今数字化飞速发展的浪潮中,人工智能已不再是一个遥远的概念,而是实实在在地渗透到了各个领域,深刻改变着我们的工作与生活方式。人力资源管理,这一关乎企业核心竞争力的关键环节,也正经历着AI技术带来的前所未有的变革。HR智能体作为这一变革中的重要成果,正逐渐成为…