事务 失效的八种情况

一、非public修饰的方法


@Transactional注解只能在在public修饰的方法下使用。

/*** 私有方法上的注解,不生效(因私有方法Spring扫描不到该方法,所以无法生成代理)*/
@Transactional
private boolean test() {//test code
}



  非public修饰的方法事务失效的原因主要有以下几点:

         1. 访问权限限制:非public修饰的方法可能无法被外部调用,而事务通常需要在外部调用的方法中开启。如果方法无法被外部调用,事务就无法生效。

         2. 事务管理器配置问题:事务管理器可能没有正确配置非public方法的事务传播行为。事务传播行为定义了事务在方法调用链中的传播方式,包括事务的开启、提交和回滚等操作。如果事务管理器没有正确配置非public方法的传播行为,事务可能无法正常生效。

         3. 代理机制问题:事务通常是通过代理机制来实现的,代理对象会拦截方法调用,并在方法调用前后进行事务管理。但是非public方法可能无法被代理对象拦截,导致事务无法生效。

         4. 异常处理问题:事务通常依赖于异常的抛出和捕获来进行事务的回滚或提交。但是非public方法可能无法抛出或捕获异常,导致事务无法正确处理异常情况。

        总之,非public修饰的方法事务失效的原因主要是因为访问权限限制、事务管理器配置问题、代理机制问题和异常处理问题等。为了确保事务的生效,应该正确配置事务管理器,并确保需要事务支持的方法具有正确的访问权限。

二、类内部访问

 例:类内部非直接访问带注解标记的方法 B,而是通过类普通方法 A,然后由 A 调用 B。

@Service
public class Demo {public void A() {this.B();}@Transactionalpublic void B() {......}
}


 

在该Service类中使用AopContext.currentProxy()获取代理对象

@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableTransactionManagement
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
 ((ServiceA)AopContext.currentProxy()).doSave(user);


 类内部访问导致事务失效的原因有以下几点:

          1. 事务控制的范围不正确:事务的开始和结束应该在整个业务逻辑的最外层,如果在类内部进行了事务的开始和结束操作,可能会导致事务的范围不正确,从而导致事务失效。

          2. 事务隔离级别不正确:事务的隔离级别决定了事务对并发操作的影响程度,如果在类内部进行了对事务隔离级别的设置,可能会导致事务的隔离级别不正确,从而导致事务失效。

          3. 异常处理不正确:在类内部进行事务操作时,如果没有正确处理异常,可能会导致事务无法正确回滚,从而导致事务失效。

          4. 数据库连接不正确:在类内部进行事务操作时,如果数据库连接不正确,可能会导致事务无法正确执行,从而导致事务失效。

          5. 并发操作冲突:在类内部进行事务操作时,如果多个线程同时对同一数据进行操作,可能会导致并发操作冲突,从而导致事务失效。

    总结起来,类内部访问导致事务失效的原因主要包括事务控制范围不正确、事务隔离级别不正确、异常处理不正确、数据库连接不正确以及并发操作冲突等。为了保证事务的正确执行,应该在整个业务逻辑的最外层进行事务的开始和结束操作,并正确处理异常、设置正确的隔离级别,同时注意数据库连接的正确性和并发操作的冲突。

三、数据库不支持事务


MyISAM和InnoDB是MySQL中两种常见的存储引擎。它们在很多方面有所不同,其中一个重要的区别是事务支持。

        事务是一组数据库操作,要么全部成功执行,要么全部回滚。事务的支持对于确保数据的完整性和一致性非常重要。下面是一些关于为什么InnoDB支持事务而MyISAM不支持事务的详细介绍:

        1. 锁级别:MyISAM使用表级锁定,这意味着当一个操作正在对表执行时,其他操作无法同时进行。这种锁定机制无法支持并发操作和事务的一致性。而InnoDB使用行级锁定,只锁定所需的行,这允许多个事务同时进行,并提高了并发性能。

         2. 崩溃恢复:InnoDB支持崩溃恢复机制,这意味着在数据库发生故障或崩溃时,可以通过恢复日志来还原到之前的状态。而MyISAM没有这种机制,因此在发生故障时可能会导致数据丢失或损坏。

         3. ACID特性:InnoDB支持ACID(原子性、一致性、隔离性和持久性)特性,这是事务处理的关键要素。原子性确保事务中的所有操作要么全部执行成功,要么全部回滚。一致性确保事务开始和结束时数据库的状态是一致的。隔离性确保并发事务之间的相互隔离,避免数据冲突。持久性确保一旦事务提交,其结果将永久保存在数据库中。而MyISAM不支持ACID特性,不能保证事务的一致性和持久性。

         4. 外键约束:InnoDB支持外键约束,可以确保数据的引用完整性。外键可以定义在一个表中的列,引用另一个表中的主键列。这样可以保证数据的完整性,避免了数据的不一致。而MyISAM不支持外键约束。

         综上所述,InnoDB支持事务是因为其使用了行级锁定、崩溃恢复机制、ACID特性和外键约束。这些特性使得InnoDB成为MySQL中更可靠和适合处理事务的存储引擎。

四、异常类型不匹配


@Transactional 注解默认只处理运行时异常( RuntimeException 和 error),而不会处理受检异常( Exception 的子类)。当抛出未被捕获的运行时异常时,Spring 会触发事务回滚操作,将之前的操作撤销;而对于未被捕获的受检异常,Spring 不会触发事务回滚操作。如果需要处理受检异常并触发事务回滚,可以通过 rollbackFor 和 noRollbackFor 属性来指定需要回滚或不需要回滚的异常类型。

/*** 非运行异常,且没有通过 rollbackFor 指定抛出的异常,不生效** @param id* @return* @throws Exception*/
@Transactional
public boolean testException(int id) throws Exception {//运行代码throw new Exception("参数异常");
}


这种情况需指定异常,如:

@Transactional(rollbackFor = Exception.class)Plain Text


五、传播属性设置问题


@Transactional默认的事务传播机制是:REQUIRED,若指定成了NOT_SUPPORTED、NEVER事务传播机制,则事物不生效,如:

@Transactional(propagation = Propagation.NOT_SUPPORTED)

六、捕获异常未抛出


例:

@Transactional
public void A(){try{......}catch(Exception e){// 未抛异常}
}


捕获异常未抛出导致事务失效的原因可能有以下几个:

             1. 异常被捕获后没有进行处理或重新抛出:在事务处理过程中,如果出现异常,应该及时捕获并进行相应的处理,例如回滚事务或者进行异常处理逻辑。如果捕获异常后没有进行处理或重新抛出,事务就会终止,导致事务失效。

              2. 异常被捕获后没有进行事务回滚:在事务处理过程中,如果出现异常,应该及时进行事务回滚,将数据库操作回滚到事务开始之前的状态。如果捕获异常后没有进行事务回滚,事务就会终止,导致事务失效。

              3. 异常被捕获后没有进行事务提交:在事务处理过程中,如果出现异常,应该及时进行事务提交,将数据库操作提交到数据库中。如果捕获异常后没有进行事务提交,事务就会终止,导致事务失效。

              4. 异常被捕获后没有进行日志记录或通知:在事务处理过程中,如果出现异常,应该及时进行日志记录或通知相关人员,以便及时处理异常情况。如果捕获异常后没有进行日志记录或通知,事务就可能失效,导致后续操作无法正常进行。

      综上所述,捕获异常未抛出导致事务失效的原因主要是没有及时处理异常、没有进行事务回滚或提交、没有进行日志记录或通知等。为了保证事务的有效性,应该在捕获异常时及时进行相应的处理和操作。

七、Bean没有纳入Spring容器管理


 例:
 

  // 注释调@Component,该类没被Spring管理,事物也是不生效的// 注释调@Component,该类没被Spring管理,事物也是不生效的
public class Demo {@Transactional(rollbackFor = Exception.class)public void A() {......}
}

Bean没有纳入Spring容器管理导致事务失效的原因可能有以下几个:

         1. 配置错误:可能是由于配置文件中没有正确配置事务管理器或者没有启用事务注解驱动。           

          2. 作用域错误:如果将Bean的作用域配置为prototype,每次获取该Bean时都会创建一个新的实例,这样事务管理器无法对其进行事务管理。

          3. AOP代理问题:Spring的事务管理通过AOP代理实现,如果Bean没有被代理,那么事务管理器无法对其进行事务控制。这可能是因为Bean没有实现接口或者没有使用基于接口的代理。

          4. Bean生命周期问题:如果Bean的生命周期不受Spring容器管理,那么事务管理器无法对其进行事务控制。这可能是因为Bean是通过其他方式创建的,而不是通过Spring容器创建的。
总之,如果Bean没有纳入Spring容器管理,那么事务管理器无法对其进行事务控制,从而导致事务失效。为了确保事务有效,需要确保Bean正确配置并纳入Spring容器管理。

八、事务方法内启动新线程进行异步操作


例:

   @Transactional(rollbackFor= BizException.class)public int transfer2(String from,String to, int money){accountDao.decrMoney(from,money);new Thread(()->{int c = 5/0;accountDao.addMoney(to,money);}).start();return 1;}


事务方法内启动新线程进行异步操作导致事务失效的原因有以下几点:

         1. 事务的隔离级别:如果事务的隔离级别是读未提交(Read Uncommitted),则新线程可能会读取到未提交的数据,导致数据不一致。

          2. 事务的提交时机:如果新线程的异步操作在事务提交之前完成,那么事务中的操作将无法回滚,导致数据不一致。

          3. 事务的传播行为:如果新线程的异步操作在事务方法内部,且事务传播行为为REQUIRED_NEW(新建事务),则新线程将会开启一个新的事务,与原事务无关,导致事务失效。

          4. 异步操作的异常处理:如果新线程的异步操作发生异常,且没有进行合适的异常处理,那么事务中的操作将无法回滚,导致数据不一致。

      综上所述,事务方法内启动新线程进行异步操作可能导致事务失效的原因主要是隔离级别、事务的提交时机、事务的传播行为以及异步操作的异常处理不当。为避免事务失效,应该在事务方法内部谨慎使用异步操作,并确保适当处理异步操作的异常,以及选择合适的事务隔离级别和传播行为。

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

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

相关文章

STM32标准库——(19)PWR电源控制

1.PWR简介 PWR属于外设部分 调用时需要先开启时钟 2.电源框图 这个图可以分为三个部分,最上面是模拟部分供电叫做VDDA,中间是数字部分供电,包括两块区域,VDD供电区域和1.8v供电区域,下面是后备供电,叫做VB…

构建读写分离的数据库集群

目录 1. 基础环境配置 (1)修改主机名 (2)编辑hosts文件 (3)配置Yum安装源 (4)安装JDK环境 2. 部署MariaDB主从数据库集群服务 (1)安装MariaDB服务 &a…

土地变化的“预言家”:DNDC模型在双碳背景下的应用探索

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到,要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时,提到要把减污降碳协同增效作为促…

怎么将电脑excel文档内的数据转换为图片形式

你平时在办公室会遇到格式转换的问题吗?比如PDF转Word,WPS转PDF,PDF转TXT,图片转PDF等。边肖最近在工作过程中遇到了类似的问题。为了更方便的查看表格,需要将Excel表格转换成图片格式。遇到这样的问题,很多…

Unity性能优化篇(八) 导入的模型网格优化设置

模型导入Unity后,可以选中这个模型,在Inspector窗口设置它的属性。下面说的都是可自定义选择优化的地方 Model选择卡: 1.在Model选项卡,启用Mesh Compression可以压缩模型,压缩程度越高,模型精度越低,但是…

基于springboot+vue的高校学生党员发展管理系统(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能实现 6.1 系统首页界面 6.2 用户登录界面 6.6 管理员后台界面 6.7 学生信息管理界面 6.8 资料管理界面 6.9 入党申请管理界面 6.10 正式党员管理界面 三、库表设计 四、论文 前言 为了进一步加强高校内党组织建设&#xff0c…

Linux:kubernetes(k8s)探针StartupProbe的使用(8)

Linux:kubernetes(k8s)pod的基础操作(6)-CSDN博客https://blog.csdn.net/w14768855/article/details/136462030?spm1001.2014.3001.5501 👆这一章里有我编写nginx-demo的一个文件 apiVersion: v1 # api文…

2024【问题解决】Github 2024无法克隆git clone自从签了2F2安全协议之后

项目场景:ping通Github但没法clone–502 问题描述 提示:ping通Github但没法clone--502: 例如:git clone https://gitclone.com/l.git/*** $ git clone https://github.com/darrenpig/Yocto Cloning into Yocto_tutorial... fatal: unable to access https://gitclone.co…

数据库:2024/3/6

作业1&#xff1a;使用C语言完成数据库的增删改 代码&#xff1a; #include <myhead.h>//定义添加员工信息函数 int Add_worker(sqlite3 *ppDb) {//准备sql语句printf("请输入要添加的员工信息:\n");//从终端获取员工信息char rbuf[128]"";fgets(r…

解决cs不能生成Linux木马的问题

要解决的问题&#xff1a;众所周知&#xff0c;msf上面的shell或者是其他的shell想反弹给cs默认情况下是只支持windows的&#xff0c;因为cs的监听模块默认没有linux的&#xff0c;但是有些主机就是用linux搭建的&#xff0c;这可怎么办呢。就要用到一个插件CrossC2。 下载插件…

[LeetCode][8]【学习日记】实现字符串转换整数 (atoi)函数

题目 8. 字符串转换整数 (atoi) 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 myAtoi(string s) 的算法如下&#xff1a; 读入字符串并丢弃无用的前导空格检查下一个字…

ky10 server 离线编译安装nginx

代码地址 https://gitcode.net/zengliguang/linux_video_audio_nginx_proxy.git 下载代码 查看服务器上下载的代码 编译安装 进入代码路径 cd /root/linux_video_audio_nginx_proxy 执行离线编译安装脚本 source centos7_nginx_offline_comp_install.sh安装编译相关依赖 …