登录 |  注册
首页 >  编程语言 >  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已自动装配,无需显示使用此注解。


九.多线程调用

原理:

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


原文链接: https://www.yukx.com/javadev/article/details/2341.html 优科学习网Spring事务不生效的原因和解决方案(全)

<<上一课程
下一课程>>
推荐文章
  • 什么是高并发?高并发(HighConcurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求,数据库的操作等。高并发
  • 首先就是创建一个普通的Java工程,起名TrySpring,最终项目如下图:然后在创建两个包分别为service、spring。service用来存放bean、配置类等,spring包用来存放我们手撸的spring注解等在service中创建UserService类,再创建Test类,在Test类中
  •      AQS(AbstractQueuedSynchronizer)是一个抽象的队列同步器,通过维护一个共享资源状态(VolatileIntState)和一个先进先出(FIFO)的线程等待队列来实现一个多线程访问共享资源的同步框架。一、AQS原理     AQS为每个共享资源都设置一个共享资源锁
  • word-break:break-all举例一般情况下,元素拥有默认的white-space:normal(自动换行,PS:不换行是white-space:nowrap),当录入的文字超过定义的宽度后会自动换行,但当录入的数据是一堆没有空格的字符或字母或数字(常规数据应该不会有吧,但有些测试人员是会
  • Bigdecimal的初始化这里对比了两种形式,第一种直接value写数字的值,第二种用string来表示        BigDecimal num1 = new BigDecimal(0.005);         BigDecimal num2 = new BigDecimal(1000000
  • 基本概念定义 双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。双亲委派机制双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载
学习大纲