@Transaction注解失效的几种场景(附有示例代码)

目录

0 说明

一、抛出检查异常导致事务不能正确回滚

二、业务方法内自己 try-catch 异常导致事务不能正确回滚

三、AOP 切面顺序导致导致事务不能正确回滚

四、非 public 方法导致的事务失效

五、父子容器导致的事务失效

六、调用本类方法导致传播行为失效

七、@Transactional注解没有保证原子行为

八、@Transactional 方法导致的 synchronized 失效


0 说明

当使用 @Transactional 注解时,可能会出现失效的情况。这种失效可能由于各种因素造成,比如异常处理、AOP切面的顺序、方法的可见性等。失效可能会导致事务无法正确地回滚或提交,从而影响数据的一致性和完整性。以下是八种常见的@Transaction注解失效的场景。

一、抛出检查异常导致事务不能正确回滚

当一个受 @Transactional 注解管理的方法中抛出了检查异常(即继承自 Exception,而非 RuntimeException),Spring 会默认将其视为受检查异常,并不会触发事务的回滚。因此,若想确保事务正确回滚,应当将异常转换为运行时异常。

@Service
public class ExampleService {

    @Autowired
    private ExampleRepository repository;

    @Transactional
    public void updateData() {
        try {
            repository.update(); // 抛出检查异常
        } catch (SQLException ex) {
            throw new RuntimeException(ex); // 转换为运行时异常
        }
    }
}

二、业务方法内自己 try-catch 异常导致事务不能正确回滚

如果在事务方法内部捕获了异常并进行了处理,而没有将其重新抛出或者抛出非 RuntimeException,则事务不会被回滚。

@Service
public class ExampleService {

    @Autowired
    private ExampleRepository repository;

    @Transactional
    public void processData() {
        try {
            // 业务逻辑
        } catch (Exception ex) {
            // 异常处理,但未重新抛出
        }
    }
}

三、AOP 切面顺序导致导致事务不能正确回滚

如果在事务方法中使用了 AOP 切面,并且切面的顺序不正确,可能会导致事务失效。通常情况下,应确保事务切面的顺序在其他切面之前。

@Aspect
@Component
public class ExampleAspect {

    @Around("execution(* com.example.service.ExampleService.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 前置逻辑
        Object result = joinPoint.proceed(); // 调用目标方法
        // 后置逻辑
        return result;
    }
}

四、非 public 方法导致的事务失效

Spring 的事务代理是通过代理对象来实现的,因此 @Transactional 注解只对公有方法有效。非公有方法如果被其他方法内部调用,则事务不会被切面代理管理,导致失效。

@Service
public class ExampleService {

    @Transactional
    public void publicMethod() {
        // 业务逻辑
    }

    @Transactional
    private void privateMethod() {
        // 业务逻辑
    }

    public void callerMethod() {
        privateMethod(); // 被调用的非公有方法内的事务失效
    }
}

五、父子容器导致的事务失效

在 Spring 中,如果父子容器的配置不正确,可能会导致事务失效。一种常见情况是父容器和子容器分别管理了事务,但子容器中的事务不会受父容器的影响,导致事务操作失效。

@Configuration
@EnableTransactionManagement
public class ParentConfig {
    @Bean
    public DataSource dataSource() {
        // 配置数据源
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

@Configuration
@EnableTransactionManagement
public class ChildConfig {
    @Bean
    public DataSource dataSource() {
        // 配置不同的数据源
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

六、调用本类方法导致传播行为失效

如果在同一个类中调用带有 @Transactional 注解的方法,Spring 的事务传播行为可能会失效。因为 Spring 通过 AOP 代理来管理事务,同一个类内的方法调用并不会触发代理,事务传播行为不会被应用。

@Service
public class ExampleService {

    @Transactional
    public void methodA() {
        methodB(); // 调用本类方法
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void methodB() {
        // 事务传播行为 REQUIRES_NEW 失效
    }
}

七、@Transactional注解没有保证原子行为

虽然 @Transactional 注解可以确保一组操作要么全部成功,要么全部失败,但它并不能保证原子性操作。如果在一个事务方法中出现多个数据库操作,并且某些操作成功,而其他操作失败,那么只有失败的那部分会回滚,而成功的部分会保留,这可能导致数据不一致。

@Service
public class ExampleService {

    @Autowired
    private ExampleRepository repository;

    @Transactional
    public void updateData() {
        repository.updateData1(); // 更新操作1
        repository.updateData2(); // 更新操作2
        // 操作2失败,但操作1已提交,数据不一致
    }
}

八、@Transactional 方法导致的 synchronized 失效

如果一个方法同时使用了 @Transactional 和 synchronized 注解,那么 synchronized 的锁将被事务代理所绕过,导致锁的失效,多个线程可能同时访问该方法,破坏了同步性。

@Service
public class ExampleService {

    @Transactional
    public synchronized void process() {
        // 事务方法
    }
}

在上述代码中,尽管 process 方法被声明为 synchronized,但由于被 @Transactional 注解修饰,Spring 的事务代理会绕过 synchronized 锁,导致同步失效。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【达梦数据库】使用DBeaver管理达梦数据库

使用DBeaver管理达梦数据库 Step1 安装相关程序 达梦8数据库DBeaver社区版 Step2 新建驱动 类型参数驱动名称DM8驱动类型Generic类名dm.jdbc.driver.DmDriverURL模板jdbc:dm://{host}:{port}默认端口5236默认数据库默认用户SYSDBA Step3 连接服务

docker部署笔记系统flatnotes

效果 安装 创建目录 mkdir -p /opt/flatnotes/data && cd /opt/flatnotes/ chmod -R 777 /opt/flatnotes/ 创建并启动容器(可以自己修改账户和密码) docker run -d \ --restart unless-stopped \ --name flatnotes \ -p "10040:8080" \ -v "/dat…

vue3 之 组合式API—生命周期函数

vue3的生命周期API 生命周期函数基本使用 1️⃣导入生命周期函数 2️⃣执行生命周期函数 传入回调 <scirpt setup> import { onMounted } from vue onMounted(()>{// 组件挂载完毕mounted执行了 }) </script>执行多次 生命周期函数是可以执行多次的&#xff…

【pikachu csrf】

cxrf 个人理解getPOST 个人理解 当被攻击用户登陆访问网站时&#xff0c;在保持登陆状态时点击小黑子&#xff08;黑客&#xff09;搭建的恶意链接而导致用户受到攻击。 举个例子 我去攻击网站&#xff0c;但是我找不到漏洞&#xff0c;这个时候我注册一个账号&#xff0c;发现…

C++——stack与queue与容器适配器

1.stack和queue的使用 1.1stack的使用 栈这种数据结构我们应该挺熟了&#xff0c;先入后出&#xff0c;只有一个出口(出口靠栈顶近)嘛 stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类&#xff0c;这些容器类应该支持以操作&#xff1a; empty&#xff1…

【leetcode题解C++】77.组合 and 216.组合总和III and 17.电话号码的字母组合

77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2&#xff1a; 输入&#xff1a…

Linux系统调试课:ftrace跟踪器介绍

文章目录 一、什么是frace跟踪器?二、Ftrace 配置三、Ftrace 文件系统四、Ftrace 初体验五、函数跟踪六、Ftrace function_graph七、函数 Profiler沉淀、分享、成长,让自己和他人都能有所收获!😄 一、什么是frace跟踪器? 操作系统内核对应用开发工程师来说就像一个黑盒,…

页面单跳转换率统计案例分析

需求说明 页面单跳转化率 计算页面单跳转化率&#xff0c;什么是页面单跳转换率&#xff0c;比如一个用户在一次 Session 过程中访问的页面路径 3,5,7,9,10,21&#xff0c;那么页面 3 跳到页面 5 叫一次单跳&#xff0c;7-9 也叫一次单跳&#xff0c; 那么单跳转化率就是要统计…

2024年【上海市安全员C3证】考试题库及上海市安全员C3证报名考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【上海市安全员C3证】考试题库及上海市安全员C3证报名考试&#xff0c;包含上海市安全员C3证考试题库答案和解析及上海市安全员C3证报名考试练习。安全生产模拟考试一点通结合国家上海市安全员C3证考试最新大纲…

刘诗诗与吴奇隆共度甜蜜亲子时光,力破离婚传闻,恩爱如初。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 最近&#xff0c;备受瞩目的狗仔队摄影师刘大锤&#xff0c;成…

删除.git的影响、git分支切换时注意事项

一、删除.git的影响 master分支文件 dev分支文件 删除.git后 文件为删除.git前分支的文件状态。 二、git分支切换时注意事项 情景&#xff1a;如果我在分支A&#xff0c;想要跳转到分支B。 git的规矩是&#xff0c;在那个分支上进行的提交&#xff0c;就算哪个分支上的工作…

代码随想录算法训练营第37天(贪心算法06 ● 738.单调递增的数字 ● 968.监控二叉树 ● 总结

贪心算法 part06 738.单调递增的数字解题思路不熟悉的基础语法知识 968.监控二叉树 &#xff08;可以跳过&#xff09;解题思路 总结 738.单调递增的数字 题目链接&#xff1a; 738.单调递增的数字 文章/视频链接: 738.单调递增的数字 解题思路 一旦出现strNum[i - 1] > …

ubuntu开机报错/dev/nume0n1p2:clean

一、前提 1、当你平时用的图站或者linux系统出现这个问题&#xff0c;首先看看你的显卡有没有换位置。 我的就是项目电脑&#xff0c;同事换了显卡位置&#xff0c;我不知道&#xff0c;当我在这个基础上继续做的时候&#xff0c;出了问题。 2、当你是第一次装显卡&#xff…

肯尼斯·里科《C和指针》第12章 使用结构和指针(1)链表

只恨当时学的时候没有读到这本书&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c; 12.1 链表 有些读者可能还不熟悉链表&#xff0c;这里对它作一简单介绍。链表(linked list)就一些包含数据的独立数据结构&#xff08;通常称为节点&#xff09;的集…

[HTML]Web前端开发技术15(HTML5、CSS3、JavaScript )表格,bordercolorlight,frame,valign,rowspan,colspan——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

DataX详解和架构介绍

系列文章目录 一、 DataX详解和架构介绍 二、 DataX源码分析 JobContainer 三、DataX源码分析 TaskGroupContainer 四、DataX源码分析 TaskExecutor 五、DataX源码分析 reader 六、DataX源码分析 writer 七、DataX源码分析 Channel 文章目录 系列文章目录DataX是什么&#xff…

探索C语言结构体:编程中的利器与艺术

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 常量与变量 1. 什么是结构体 在C语言中本身就自带了一些数据类型&#x…

前端实现标题滚动点击导航

效果图 右边滚动的html代码 <div class"right-box"><el-tabs v-model"isScrollNow" tab-position"right" class"updateTab" tab-click"scrollTo"style"height: fit-content;"><el-tab-pane label…

C语言之随心所欲打印三角形,金字塔,菱形(倒金字塔)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 目录 三角形 金字塔 倒金字塔 菱形 三角形 题目&#xff1a;根据输入的行数打印对应的三角形。&#xff08;用 * 号打印&#xff09; #includ…

Python学习路线 - Python高阶技巧 - SQL入门和实战

Python学习路线 - Python高阶技巧 - SQL入门和实战 SQL章节前言无处不在的SQL 数据库介绍无处不在的数据库数据库如何存储数据数据库如何存储数据数据库管理系统(数据库软件)数据库和SQL的关系 Mysql的安装Mysql的介绍Mysql的版本MySQL安装配置环境变量 Mysql的入门使用在命令提…
最新文章