Spring事务失效之常见场景分析

目录
  • 一、事务方法访问修饰符非public,导致事务失效
  • 二、@Transactional注解的方法抛出的异常不是spring的事务支持的异常,导致事务失效
  • 三、数据表本身是不支持事务,导致事务失效
  • 四、@Transactional注解所在的类没有被spring管理,导致事务失效
  • 五、catch掉异常之后,没有再次抛出异常,导致事务失效
  • 六、方法自身(this)调用问题,导致事务失效
  • 七、数据源没有配置事务管理器
  • 八、传播类型不支持事务
  • 九、多线程调用,导致事务失效
  • 总结

一、事务方法访问修饰符非public,导致事务失效

1、实例

2、解决

方式一:将方法修饰符改为public

方式二:开启AspectJ代理模式

3、注意

  

如果事务是static、final的,同样无法通过动态代理,事务也是不会生效的。  

Spring的声明式事务是基于动态代理实现的,我们无法重写final修饰的方法;  

不管是JDK动态代理还是Cglib的动态代理,就是要通过代理的方式获取到代理的具体对象,而static方法修饰的方法是属于类的,不属于任何对象,所以static方法不能被重写,即便写法上是重写,但是并不具备重写的含义,也就是说static方法也不被进行动态代理。

二、@Transactional注解的方法抛出的异常不是spring的事务支持的异常,导致事务失效

1、实例

2、解决

3、注意  

spring的事务只支持未检查异常(unchecked),不支持已检查异常(checked)。

三、数据表本身是不支持事务,导致事务失效

1、实例

如果使用MySQL且存储引擎是MyISAM,则事务是不起作用的,原因是MyIASM不支持事务。

2、解决  

数据表可以改为InnoDB存储引擎,支持事务

四、@Transactional注解所在的类没有被spring管理,导致事务失效

1、实例

2、解决  

加上@Service注解或者使用其他能注册成Spring Bean的方式或注解。

五、catch掉异常之后,没有再次抛出异常,导致事务失效

1、实例

2、解决

3、注意  

如果在加有事务的方法内,使用了try…catch…语句块对异常进行了捕获,而catch语句块没有throw new RuntimeException异常或者Spring支持的异常类型,则事务不会回滚。

六、方法自身(this)调用问题,导致事务失效

非事务方法insert()中调用的自身类的事务方法insertUser()。

1、实例

2、解析

3、解决

方式一:

方式二:

方式三:

方式四:

七、数据源没有配置事务管理器

导致事务失效

八、传播类型不支持事务

导致事务失效

1、实例

2、注意

九、多线程调用,导致事务失效

1、实例

2、解析

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring事务失效的场景梳理总结

    目录 概述 事务的传播类型 事务隔离级别 事务失效的场景 概述 Spring针对Java Transaction API (JTA).JDBC.Hibernate和Java Persistence API(JPA)等事务 API,实现了一致的编程模型,而Spring的声明式事务功能更是提供了极其方便的事务配置方式,配合Spring Boot的自动配置,大多数Spring Boot项目只需要在方法上标记@Transactional注解,即可一键开启方法的事务性配置. 但是,事务如果没有被正确使用,

  • Spring详细讲解事务失效的场景

    目录 1)未被Spring管理 2)数据库引擎不支持事务 3)事务方法没有被public修饰 4)方法使用final修饰 5)同一类中方法调用 6)未开启事务 7)多线程调用 8)错误的传播行为 9)自己try…catch…掉了异常 10)手动抛出了错误的异常 11)自定义回滚异常 12)嵌套事务回滚多了 1)未被Spring管理 使用Spring事务的前提是:对象要被Spring管理,事务方法所在的类要被加载为bean对象 如果事务方法所在的类没有被加载为一个bean,那么事务自然就失效了,示

  • Spring事务失效场景实例详解

    1.Spring事务最终依赖的数据库的事务,如果用的是mysql的话,执行引擎要是innodb;因为只有innoDB 支持事务. 2.Spring的事务是原理是aop,所以加事务所在bean是要Spring容器管理的:自己new出来的对象肯定是不行的. 3.Spring事务标签@Transactional必须注解在public方法上.private.protected.default以及finally修饰的方法或者类,以及静态方法,事务都会失效的. 4.同一个类中内部方法调用,事务会失效的.调用

  • Spring事务失效的各种场景(13种)

    目录 一.访问权限 二.方法用final修饰 三.方法内部调用 四.没有被spring管理 五.多线程调用 六.设计的表不支持事务 七.没有开启事务 八.错误的事务传播 九.自己捕获了异常 十.手动抛出别的异常 十一.自定义回滚异常 十二.嵌套事务回滚过头 十三.编程式事务 一.访问权限 Java的访问权限主要是:private.default.protected.public,它们的权限则是依次变大.如果我们在开发的时候定义错误的访问权限,就会导致事务出现问题 @Service public

  • Spring事务失效场景的详细整理

    目录 前言 数据库引擎不支持事物 方法不是 public 的 自身调用问题 不支持事物 异常被吃掉 异常类型错误 总结 前言 项目中用Spring的 @Transactional 注解控制事务,使用中时常出现事物不生效的场景,本文仅限于日常项目开发中的点滴整理总结,总结以下几点,以备后续参考排查;可能不全,列举出来希望可以帮助有需要的同学,避免踩坑. 数据库引擎不支持事物 这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用

  • 一篇文章带你了解spring事务失效的多种场景

    目录 前言 一 事务不生效 1.访问权限问题 2. 方法用final修饰 3.方法内部调用 4.未被spring管理 5.多线程调用 6.表不支持事务 7.未开启事务 二 事务不回滚 1.错误的传播特性 2.自己吞了异常 3.手动抛了别的异常 4.自定义了回滚异常 5.嵌套事务回滚多了 三 其他 1 大事务问题 2.编程式事务 总结 前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要

  • Spring事务失效问题分析及解决方案

    这篇文章主要介绍了Spring事务失效问题分析及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 隔离级别 在 TransactionDefinition.java 接口中,定义了"四种"的隔离级别枚举: /** * [Spring 独有]使用后端数据库默认的隔离级别 * * MySQL 默认采用的 REPEATABLE_READ隔离级别 * Oracle 默认采用的 READ_COMMITTED隔离级别 */ int ISOL

  • 8个Spring事务失效场景详解

    目录 前言 Spring事务原理 Spring事务失效场景 1. 抛出检查异常 2. 业务方法本身捕获了异常 3. 同一类中的方法调用 4. 方法使用 final 或 static关键字 5. 方法不是public 6. 错误使用传播机制 7. 没有被Spring管理 8. 多线程 总结 前言 作为Java开发工程师,相信大家对Spring种事务的使用并不陌生.但是你可能只是停留在基础的使用层面上,在遇到一些比较特殊的场景,事务可能没有生效,直接在生产上暴露了,这可能就会导致比较严重的生产事故.

  • MySQL中索引失效的常见场景与规避方法

    前言 之前有看过许多类似的文章内容,提到过一些sql语句的使用不当会导致MySQL的索引失效.还有一些MySQL"军规"或者规范写明了某些sql不能这么写,否则索引失效. 绝大部分的内容笔者是认可的,不过部分举例中笔者认为用词太绝对了,并没有说明其中的原由,很多人不知道为什么.所以笔者绝对再整理一遍MySQL中索引失效的常见场景,并分析其中的原由供大家参考. 当然请记住,explain是一个好习惯! MySQL索引失效的常见场景 在验证下面的场景时,请准备足够多的数据量,因为数据量少时

  • Spring事务失效的几种原因

    数据库引擎不支持事务 在MySQL数据库中有几种引擎(InnoDB,MyISAM,Memory等等),仅仅InnoDB支持事务,如果数据库底层都不支持事务的话,那么再怎么折腾都是白搭. @transactional加在private方法上 @Transactional只能加在public方法上,如果需要在private方法中加入事务,可以使用Aspect配transactionManager使用. 本类方法调本类另一个方法 例如: @Service public class UserServic

  • Spring事务失效场景原理及解决方案

    1.事务失效-自身调用(通过REQUIRES.REQUIRES_NEW传播属性):自身调用即调该类自己的方法. 同类OrderServiceImpl 中 doSomeThing()方法 不存在事务,该方法去调用本类中的存在事务注解的 insertAndUpdateOrderInfo() 方法.但是insertAndUpdateOrderInfo() 其实是无法保证预想的事务性. 示列验证: OrderServiceImpl.insertAndUpdateOrderInfo方法中upateData

  • 解决try-catch捕获异常信息后Spring事务失效的问题

    一.首先在Spring Boot项目中,手动添加异常方法进行测试 @Transactional(rollbackFor=Exception.class) //表示此方法有异常时触发Spring事务 @Override public CommonResult<User> saveUser(User user) { int insert = baseMapper.insert(user); try { // 添加异常,并进行捕获 int a = 10/0; }catch (Exception e)

随机推荐