导致事物失效的场景有哪些 ?

news2024/10/7 2:31:53

目录

1. 导致事物失效的场景有哪些 ?

1.1 为什么 @Transaction 修饰非 public 方法会导致事物失效 ?

1.2 代码中使用 try/catch 处理了异常为什么会导致事物失效 ?

1.3 为什么在类内部调用 @Transaction 修饰的方法会导致事务失效 ?

1.4 数据库不支持事物,导致事物失效


1. 导致事物失效的场景有哪些 ?

导致事物失效的常见场景有 4 个:

  1. @Transaction 修饰非 public 方法;
  2. 代码中使用 try/catch 处理了异常;
  3. 在类内部调用 @Transaction 修饰的方法;
  4. 数据库不支持事物

1.1 为什么 @Transaction 修饰非 public 方法会导致事物失效 ?

【浅层原因】

@Transaction 注解底层源码限制了必须是 public 方法才能执行后续的流程。

【深层原因】

1.前置知识:

        首先,我们得知道 @Transaction 底层是基于动态代理实现的,在执行目标方法之前,代理对象会帮我们开启事务,在执行完目标方法之后,代理对象会帮我们进行提交或回滚事物。其次动态代理的底层只有 JDK Proxy CGLib 两种实现。

2.此时我们再来细究一下这两种代理为什么只能代理被 public 修饰的方法:

JDK Proxy :要求被代理类一定要实现接口,JDK 生成的代理类也需要实现这个接口(为了保证方法名一致),而接口中的方法的访问控制符都是 public,所以 JDK Proxy 只能代理公共方法。

② CGLib:通过生成被代理类的子类来实现代理,而子类继承父类的方法,只能继承父类中使用 public 和 protected 修饰的方法又因为 protected 修饰的方法不允许跨包访问非子类方法,所以被代理类的方法访问是受限制的,因此 CGLib 只有代理 public 修饰的方法,它的功能才是完整的。

1.2 代码中使用 try/catch 处理了异常为什么会导致事物失效 ?

我们都知道使用 @Transaction 注解后,当程序抛出异常时,它会自动帮我们回滚。

当我们手动加了 try/catch 之后,为什么事物就不会自动回滚了 ?

这就得分析 @Transaction 的底层源码了:

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
        throws Throwable {
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass);

    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        //开启事务
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;
        try {
            //方法调用
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable ex) {
            // target invocation exception
            //回滚事务
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            cleanupTransactionInfo(txInfo);
        }
        //提交事务
        commitTransactionAfterReturning(txInfo);
        return retVal;
    } else {
        // .....
    }
}

        从上述源码,我们就可以看出问题了,当程序抛出异常的时,@Transaction 注解底层会捕获异常并调用回滚方法,而如果我们手动处理了异常,那么 @Transaction 注解就没办法监控到异常了,也就不会执行回滚方法了。

那添加了 try/catch 之后,我们该怎么让事物进行回滚呢 ?

1. 重新抛出异常

try {
    int i = 10 / 0;
} catch(Exception e) {
    // 重新抛出异常
    throw e;
}

2. 手动回滚事物(推荐)

try {
    int i = 10 / 0;
} catch(Exception e) {
    // 手动回滚事物
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

1.3 为什么在类内部调用 @Transaction 修饰的方法会导致事务失效 ?

        因为 @Transaction 是基于动态代理实现的,而当我们在类内部调用 @Transaction 修饰的方法时,就不是通过代理对象调用的,而是通过 this 对象调用的,这样就绕过了代理对象,从而就导致事物失效了。

1.4 数据库不支持事物,导致事物失效

最后一条数据库不支持事物,那就不用说了,肯定不生效。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一图胜千言!数据可视化多维讲解(Python)

数据聚合、汇总和可视化是支撑数据分析领域的三大支柱。长久以来&#xff0c;数据可视化都是一个强有力的工具&#xff0c;被业界广泛使用&#xff0c;却受限于 2 维。在本文中&#xff0c;作者将探索一些有效的多维数据可视化策略&#xff08;范围从 1 维到 6 维&#xff09;。…

批处理启动程序

&#x1f495;批处理启动程序 新建一个txt&#xff0c;把后缀改成bat&#xff0c;编辑脚本&#xff1a;start exe路径即可&#xff1a;

$nextTick使用

在Vue中&#xff0c;$nextTick是一个实例方法&#xff0c;用于在DOM更新之后执行回调函数。它可以用于在更新视图后执行一些操作&#xff0c;例如访问更新后的DOM元素或执行其他异步任务。 以下是$nextTick的使用方法&#xff1a; this.$nextTick(() > {// 在DOM更新后执行…

【若依框架RuoYi-Vue-Plus 图片回显不显示问题,OSS文件上传或者本地上传】

一、问题 1.设计表 product&#xff08;商品表&#xff09; 有 id &#xff08;id&#xff09; name&#xff08;商品名&#xff09;icon&#xff08;图标&#xff09; 2.使用若依代码生成功能&#xff0c;导入product表&#xff0c;代码生成。 3.将生成的代码导入到项目中得到…

Vue-Router 一篇搞定 Vue3

前言 在 Web 前端开发中&#xff0c;路由是非常重要的一环&#xff0c;但是路由到底是什么呢&#xff1f; 从路由的用途上讲 路由是指随着浏览器地址栏的变化&#xff0c;展示给用户不同的页面。 从路由的实现原理上讲 路由是URL到函数的映射。它将 URL 和应用程序的不同部分…

PXE 装机(五十)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、PXE是什么 二、PXE的组件 三、配置vsftpd 四、配置tftp 五、准备pxelinx.0文件、引导文件、内核文件 ​六、配置dhcp 七、创建default文件 八、配置pxe无人值守…

C语言圣经KR笔记 1.10外部变量和作用域

1.10外部变量和作用域 上一节main中的变量&#xff0c;如line、longest等等&#xff0c;对main来说是私有的或者说是局部的。因为它们是在main中定义的&#xff0c;其他函数不能直接访问它们。其他函数中的变量也是如此&#xff0c;例如&#xff0c;getline中的变量 i 与copy中…

C语言:static关键字的使用

1.static修饰局部变量 这是static关键字使用最多的情况。我们知道局部变量是在程序运行阶段在栈上创建的&#xff0c;但是static修饰的局部变量是在程序编译阶段在代码段&#xff08;静态区&#xff09;创建的。所以在static修饰的变量所在函数执行结束后该变量依然存在。 //…

C++(17):标准库特殊设施

tuple 类型 tuple是类似pair的模板。 每个pair的成员类型都不相同&#xff0c;但每个 pair都恰好有两个成员。不同tuple类型的成员类型也不相同&#xff0c;但一个tuple可以有任意数量的成员。 每个确定的tuple类型的成员数目是固定的&#xff0c;但一个tuple类型的成员数目可…

OS 死锁处理

如果P先申请mutex 则mutex从1置零&#xff0c;假设申请到的empty 0则empty变成-1阻塞态 同理C中mutex从0变为-1&#xff0c;那么如果想离开阻塞态&#xff0c;那么就需要执行V&#xff08;empty&#xff09;但是如果执行V&#xff08;empty&#xff09;就需要P&#xff08;mu…

postgresql-窗口函数

postgresql-窗口函数 简介窗口函数的定义分区选项&#xff08;PARTITION BY&#xff09;排序选项&#xff08;ORDER BY&#xff09;窗口选项&#xff08;frame_clause&#xff09; 聚合窗口函数排名窗口函数演示了 CUME_DIST 和 NTILE 函数 取值窗口函数 简介 常见的聚合函数&…

飞致云开源社区月度动态报告(2023年8月)

自2023年6月起&#xff0c;中国领先的开源软件公司FIT2CLOUD飞致云以月度为单位发布《飞致云开源社区月度动态报告》&#xff0c;旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况&#xff0c;以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源大屏…

开讲啦!0基础也能玩转飞桨开源社区

作为cs/ai学生&#xff0c;你是否经历过这些至暗时刻&#xff1a; 希望快速入门深度学习&#xff0c;无奈网上到处都是看不懂“黑话”一遍遍计算综测小数点后四位&#xff0c;不断在保研边缘反复横跳看着“洁白如新”的履历叹气&#xff0c;一听到“考研复试”就头皮发麻“0实习…

【ES6】Promise.allSettled的用法

Promise.allSettled() 是一个Promise方法&#xff0c;用于处理一个Promise数组&#xff0c;返回一个新的Promise数组&#xff0c;每个元素对应原始Promise的状态。这个方法可以用于处理多个异步操作&#xff0c;并且能够获取每个操作的结果和状态。 下面是Promise.allSettled(…

基于蛇优化算法优化的BP神经网络(预测应用) - 附代码

基于蛇优化算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于蛇优化算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.蛇优化优化BP神经网络2.1 BP神经网络参数设置2.2 蛇优化算法应用 4.测试结果&#xff1a;5.Matlab代…

ChatGPT~Error1015You are being rate limited

目录 问题背景 问题的原因 下来说说解决方案 总结 问题背景 今天使用Chatgpt的时候突然出现"You are being rate limited"的错误提示。 问题的原因 小问题了&#xff0c;又不是第一次被弄出来了&#xff0c;莫慌。 让我们先看看Chatgpt自己是怎么解释这个问题…

GE Diary 0001

今天是入职GEHC的第一天&#xff0c;虽然是OD岗位&#xff0c;但是员工氛围暂时没感觉有什么差异&#xff0c;领导也很随和。 公司印象&#xff1a;GEHC目前给我的印象是典型的外企&#xff1a;朝九晚五、无需打卡&#xff08;OD岗位需要打本公司的卡&#xff09;、短小精悍的会…

2781. 最长合法子字符串的长度

2781. 最长合法子字符串的长度 C代码&#xff1a;滑动窗口、哈希表 typedef struct{char* str;UT_hash_handle hh; } HashTable;HashTable* head;void AddToHash(char* str) {HashTable* out (HashTable*)malloc(sizeof(HashTable));out->str str;HASH_ADD_STR(head, str…

Opencv基于文字检测去图片水印

做了一个简单的去水印功能&#xff0c;基于文字检测去图片水印。效果如下&#xff1a; 插件功能代码参考如下&#xff1a; using namespace cv::dnn; TextDetectionModel_DB *textDetector0; void getTextDetector() {if(textDetector)return;String modelPath "text_de…

C++ 学习系列 -- const 关键字

C 中引入了 const 关键字&#xff0c;被 const 关键字修饰的变量其值不能修改&#xff0c;是只读的。 一 const 变量的初始化与存储 1. const 变量初始化时就需要赋初值&#xff0c;否则无法编译通过 二 const 与指针 指针常量&#xff1a; 指针所指向的值不可改变&…