登录 |  注册
首页 >  编程语言 >  Spring开发实战学习笔记 >  Spring事务不生效的原因和解决方案(全)

Spring事务不生效的原因和解决方案(全)

一.抛出事务不支持的异常

原理:

Spring事务默认支持RuntimeException异常,抛出的异常为RuntimeException异常及其子类异常事务均可生效,而我们日常常见的异常基本都继承自RuntimeException,所以无需指定异常类型事务也能生效。

但若手动抛出Exception异常,而Exception是RuntimeException的父类,会导致事务不生效。

解决方案:

1.指定Spring事务异常捕获类型

@Transactional(rollbackFor = Exception.class)

2.抛出Spring事务支持的异常类型

throw new RuntimeException("手动抛出运行时异常");


二.使用了try catch

原理:

异常被try catch块捕获,导致事务失效

解决方案:

在catch中抛出Spring事务支持的异常。


三.事务方法为私有方法

原理:

Spring声明式事务基于动态代理实现,private方法不能被代理,事务不会生效。

此外,static修饰的方法属于类,不属于任何对象,也不能被代理,事务不生效。

final修饰的方法无法重写,也就不能被代理,事务也不会生效。

解决方案:

方法用public修饰,不要用static、final修饰


四.类未被Spring管理

原理:

Spring实现对象的动态代理,首先这个对象要交由Spring管理。

解决方案:

将类交由Spring管理,可添加@Service注解,或使用其他能够注册成Spring Bean的注解或方法。


五.一个方法调用本类另一个方法,事务失效

原理:

@Transactional基于AOP实现,而AOP又是基于动态代理实现,直接调用本类方法或使用this调用本类方法,均不是Spring的代理对象,无法实现动态代理,事务也就不会生效。

解决方案:

1.将两个方法合并为一个方法,用@Transactional修饰。

2.将被调用的方法放到另一个被Spring管理的类中,用实例对象调用,

3.用@Autowired在本类中注入本类实例,再用注入的实例对象调用该方法。

4.手动获取本类的代理,用代理调用该方法((TestService)AopContext.currentProxy()).myTest();


六.数据表不支持事务

原理:

Spring事务基于数据库事务实现,有些数据表本身不支持事务,如MySql的MyISAM引擎,事务自然不生效。

解决方案:

将数据表改用支持事务的引擎,如MySql的InnoDB引擎。


七.Spring事务传播级别设置为不支持事务

原理:

@Transactional(propagation = Propagation.NOT_SUPPORTED)  不支持事务,若存在事务则挂起

@Transactional(propagation = Propagation.NEVER)  不使用事务,若存在事务则抛异常

解决方案:

使用Spring默认的传播级别(PROPAGATION_REQUIRED),或其他支持事务的传播级别。


八.未开启事务

解决方案:

@EnableTransactionManagement开启事务,Spring boot已自动装配,无需显示使用此注解。


九.多线程调用

原理:

不同线程使用不同的数据库链接,基于同一数据库连接的事务才能同时提交或回滚,因此事务不生效。


上一篇: 网站返回码枚举类定义 ResponseCodeEnum
下一篇: Mybatis无法找到xml文件,Invalid bound statement (not found)
推荐文章
  • 在HTML中,如果你想让一个输入框(input元素)不可编辑,你可以通过设置其readonly属性来实现。示例如下:input type="text" value="此处内容不可编辑" readonly在上述代码中,readonly属性使得用户无法修改输入框中的内容。另外,如果你希望输入框完全不可交
  • ASP.NET教程ASP.NET又称为ASP+,基于.NETFramework的Web开发平台,是微软公司推出的新一代脚本语言。ASP.NET是一个使用HTML、CSS、JavaScript和服务器脚本创建网页和网站的开发框架。ASP.NET支持三种不一样的开发模式:WebPages(Web页面)、
  • C# 判断判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。下面是大多数编程语言中典型的判断结构的通常形式:判断语句C#提供了以下类型的判断语句。点击链接查看每个语句的细节。语句描述if语句一个 if语句 由一个布尔表达式后跟
  • C#循环有的时候,可能需要多次执行同一块代码。通常情况下,语句是顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。编程语言提供了允许更为复杂的执行路径的多种控制结构。循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的通常形式:循环类型C#提供了以下几种循环类型
  • C#数组(Array)数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,一般认为数组是一个同一类型变量的集合。声明数组变量并不是声明number0、number1、...、number99一个个单独的变量,而是声明一个就像numbers这样的变量,然后使用numbers[0]
  • ASP.NET是一个由微软公司开发的用于构建Web应用程序的框架,它是.NETFramework的一部分。它提供了一种模型-视图-控制器(MVC)架构、Web表单以及最新的ASP.NETCore中的RazorPages等多种开发模式,可以用来创建动态网页和Web服务。以下是一些基础的ASP.NET编
学习大纲