事务控制失效的八种常见原因

2024-03-07 16:52

本文主要是介绍事务控制失效的八种常见原因,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、非public修饰的方法

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

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

二、类内部访问

类内部非直接访问带注解标记的方法 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);

三、数据库不支持事务

MySQL中,MyISAM引擎不支持事物,InnoDB 支持事物

四、异常类型不匹配

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

/*** 非运行异常,且没有通过 rollbackFor 指定抛出的异常,不生效** @param id* @return* @throws Exception*/@Transactionalpublic void insertAll(PoMaster master) throws Exception {poMasterDao.insert(master);if(1 == 1){throw new Exception("测试异常");}poItemDao.insertList(master.getItems());}

五、传播属性设置问题

propagation属性错误

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

@Transactional(propagation = Propagation.NOT_SUPPORTED)

 

六、捕获异常未抛出

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

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

// 注释调@Component,该类没被Spring管理,事物也是不生效的

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

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

@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;}

这篇关于事务控制失效的八种常见原因的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/784196

相关文章

SQL中redo log 刷⼊磁盘的常见方法

《SQL中redolog刷⼊磁盘的常见方法》本文主要介绍了SQL中redolog刷⼊磁盘的常见方法,将redolog刷入磁盘的方法确保了数据的持久性和一致性,下面就来具体介绍一下,感兴趣的可以了解... 目录Redo Log 刷入磁盘的方法Redo Log 刷入磁盘的过程代码示例(伪代码)在数据库系统中,r

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

SQL BETWEEN 的常见用法小结

《SQLBETWEEN的常见用法小结》BETWEEN操作符是SQL中非常有用的工具,它允许你快速选取某个范围内的值,本文给大家介绍SQLBETWEEN的常见用法,感兴趣的朋友一起看看吧... 在SQL中,BETWEEN是一个操作符,用于选取介于两个值之间的数据。它包含这两个边界值。BETWEEN操作符常用

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve