精华内容
下载资源
问答
  • Spring 事务失效

    2019-08-29 16:18:56
    Spring 事务失效 ...

    Spring 事务失效

    [问题]

           Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring AOP啊,事务管理真轻松啊,真轻松;事务管理代码没有了,脑不酸了,手不痛了,一口气全配上了事务;轻量级,测试起来也简单,嘿!”。不管从哪个角度看,轻量级声明式事务都是一件解放生产力的大好事。所以,我们“一直用它”。

     

          不过,最近的一个项目里,却碰到了一个事务管理上的问题:有一个服务类,其一个声明了事务的方法,里面做了三次插入SQL操作,但是在后面出错回滚时,却发现前面插入成功了,也是说,这个声明了事务的方法,实际上并没有真正启动事务!怎么回事呢?难道Spring的声明式事务失效了?

          

    [探幽]

         其实以前也会碰到有人说,Spring的事务配置不起作用,但是根据第一反应和以往经验,我总会告诉他,肯定是你的配置有问题啦;所以这一次,我想也不会例外,大概是把事务注解配在了接口上而不是实现方法上,或者,如果是用XML声明方式的话,很可能是切入点的表达式没有配对。

     

         不过,在检查了他们的配置后,却发现没有配置问题,该起事务的实现方法上,用了@Transactional事务注解声明,XML里也配了注解驱动<tx:annotation-driven .../>,配置很正确啊,怎么会不起作用?

     

         我很纳闷,于是往下问:

         问1:其他方法有这种情况么?

         答1:没有。

         问2:这个方法有什么特别的么(以下简称方法B)?

         答2:就是调后台插了三条记录啊,没啥特别的。

         问3:这个方法是从Web层直接调用的吧?

         答3:不是,是这个Service类(以下简称ServiceA)的另外一个方法调过来的(以下简称方法A)。

         问4:哦,那个调用它的方法配了事务么(问题可能在这了)?

         答4:没有。

         问5:那WEB层的Action(用的是Struts2),调用的是没有声明事务的方法A,方法A再调用声明了事务的方法B?

         答5:对的。

         问6:你直接在方法A上加上事务声明看看

         答6:好。。。

         

         看来可能找到问题所在了,于是把@Transactional也加在方法A上,启动项目测试,结果是:事务正常生效,方法A和方法B都在一个事务里了。

     

         好了,现在总结一下现象:

         1、ServiceA类为Web层的Action服务

         2、Action调用了ServiceA的方法A,而方法A没有声明事务(原因是方法A本身比较耗时而又不需要事务)

         3、ServiceA的方法A调用了自己的方法B,而方法B声明了事务,但是方法B的事务声明在这种情况失效了。

         4、如果在方法A上也声明事务,则在Action调用方法A时,事务生效,而方法B则自动参与了这个事务。 

     

           我让他先把A也加上事务声明,决定回来自己再测一下。

         

           这个问题,表面上是事务声明失效的问题,实质上很可能是Spring的AOP机制实现角度的问题。我想到很久以前研究Spring的AOP实现时发现的一个现象:对于以Cglib方式增强的AOP目标类,会创建两个对象,一个事Bean实例本身,一个是Cglib增强代理对象,而不仅仅是只有后者。我曾经疑惑过这一点,但当时没有再仔细探究下去。

         

          我们知道,Spring的AOP实现方式有两种:1、Java代理方式;2、Cglib动态增强方式,这两种方式在Spring中是可以无缝自由切换的。Java代理方式的优点是不依赖第三方jar包,缺点是不能代理类,只能代理接口。

     

          Spring通过AopProxy接口,抽象了这两种实现,实现了一致的AOP方式:


    现在看来,这种抽象同样带了一个缺陷,那就是抹杀了Cglib能够直接创建普通类的增强子类的能力,Spring相当于把Cglib动态生成的子类,当普通的代理类了,这也是为什么会创建两个对象的原因。下图显示了Spring的AOP代理类的实际调用过程:




    因此,从上面的分析可以看出,methodB没有被AopProxy通知到,导致最终结果是:被Spring的AOP增强的类,在同一个类的内部方法调用时,其被调用方法上的增强通知将不起作用。

        

          而这种结果,会造成什么影响呢:

          1:内部调用时,被调用方法的事务声明将不起作用

          2:换句话说,你在某个方法上声明它需要事务的时候,如果这个类还有其他开发者,你将不能保证这个方法真的会在事务环境中

          3:再换句话说,Spring的事务传播策略在内部方法调用时将不起作用。不管你希望某个方法需要单独事务,是RequiresNew,还是要嵌套事务,要Nested,等等,统统不起作用。

          4:不仅仅是事务通知,所有你自己利用Spring实现的AOP通知,都会受到同样限制。。。。

     

    [解难]

         

          问题的原因已经找到,其实,我理想中的AOP实现,应该是下面这样:


    只要一个Cglib增强对象就好,对于Java代理方式,我的选择是毫不犹豫的抛弃。

     

          至于前面的事务问题,只要避开Spring目前的AOP实现上的限制,要么都声明要事务,要么分开成两个类,要么直接在方法里使用编程式事务,那么一切OK。

    展开全文
  • spring 事务失效

    2016-08-29 15:29:45
    spring事务失效大体上有这几个原因,或者说可以从这几个方面着手检查,步步为营,一步步的找到问题所在。这也是排查问题的一般方法。 1.数据库是否已经开启了事务支持,尤其是mysql,检查表的引擎是否为innodb引擎。...
    最近几天发现项目中spring的声明式事务失效。找了很多资料看了不少博客,现在mark一下,给自己留个印象,也给后来者打开一个思路吧。

    spring事务失效大体上有这几个原因,或者说可以从这几个方面着手检查,步步为营,一步步的找到问题所在。这也是排查问题的一般方法。

    1.数据库是否已经开启了事务支持,尤其是mysql,检查表的引擎是否为innodb引擎。
    2.检查spring注解配置是否重复扫描,在扫描@Controller时,不扫描@Service等。
    3.shiro和spring aop会有冲突。解决办法是先不注入relam,在spring监听启动完成后再注入。

    第三种情况比较特殊,在试用shiro做权限控制的时候,经常涉及到自定义relam,在relam中不能自动注入service依赖。而应该在spring监听运行完毕之后再进行依赖的绑定。这次我遇到的就是这个问题。这个问题比较小众,用shrio的才可能会遇到。但是为什么会出现这样的问题。我也没有太闹明白。留待以后再深究,也希望大神能给我解惑。
    展开全文
  • Spring事务失效

    2021-03-24 15:45:33
    一、数据库引起不支持事务 Mysql的MyISAM引擎不支持...@Transactional只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启AspectJ代理模式 四、注解方法只有外部类调用才能生效 ...

    一、数据库引起不支持事务

    Mysql的MyISAM引擎不支持事务,InnoDB支持事务

    二、没有被Spring管理

    没有被加载程Bean

    三、事务注解方法只能用于public方法上

    @Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式

    四、注解方法只有外部类调用才能生效

    五、多数据源,注解指定对应的事务管理器

     @Transactional("DbTransactionManager")

    六、Propagation.NOT_SUPPORTED不以事务运行

    七、代码逻辑问题

    7.1、异常被捕获处理:未抛出异常没有触发事务回滚

    7.2、异常被捕获处理:未抛出RuntimeException异常,例如抛出Exception异常

    7.3、异常捕获抛出Exception异常,需要增加回滚类型 @Transactional(rollbackFor = {Exception.class} )

    展开全文
  • Spring事务失效的原因

    2016-07-04 17:31:12
    Spring事务失效
    1.如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB。
    2.如果使用了spring+mvc,则context:component-scan重复扫描问题可能会引起事务失败。
    3.@Transactional 注解开启配置,必须放到listener里加载,如果放到DispatcherServlet的配置里,事务也是不起作用的。
    4.@Transactional 注解只能应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,事务也会失效。
    5.Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
    展开全文
  • 详细整理Spring事务失效的具体场景及解决方案

    万次阅读 多人点赞 2020-08-04 22:25:14
    好多小伙伴可能只是简单了解一下,遇到事务失效的情况,便会无从下手,溪源此篇文章给大家整理了一下常见Spring事务失效的场景,希望开发过程尽量避免踩坑,造成时间精力的浪费。 溪源按照最基本的使用方式以及常见...
  • 主要介绍了Spring事务失效问题分析及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • springmvc导致spring事务失效
  • spring事务失效场景

    千次阅读 2020-01-11 15:23:23
    spring事务失效场景 添加@Transactional后的方法,不会直接操作数据库,例如保存方法,在执行完保存语句后,数据库并没有出现该数据,只有方法结束之后,才会正式保存到数据库。 1、首先使用如下代码 确认你的bean ...
  • spring事务失效原因

    2020-03-20 17:33:35
    Cannot find current proxy: Set ‘exposeProxy’ property on Advised to ‘true’ to 以及Spring事务失效的原因和解决方案: https://blog.csdn.net/mameng1988/article/details/85548812.
  • spring事务失效场景梳理 @Transactional 应用在非 public 方法上 spring 事务底层在扫描 @Transactional 注解时会直接不会获取非 public 的方法上的 @Transactional 注解的属性信息 @Transactional 的 rollback...
  • Spring 事务失效的场景

    2020-12-22 10:08:54
    Spring 事务失效的场景 第一种:try { }catch (){}不抛出异常 try { }catch (){}不抛出异常 ,spring 事务不会捕捉到异常,导致事务失效。 @Transactional public void insertTestCatchException() { try { ...
  • spring事务失效排查

    2019-06-17 20:56:27
    spring事务失效排查 完成线下备货成功后需要更改订单状态,涉及中订单状态的更改以及和中订单相关联的小订单状态的更改,两种订单状态的更改必须是要同时成功和失败的,一种失败后另一种成功了也需要回滚。这就需要...
  • spring-kafka导致spring事务失效的解决办法 spring-boot版本:2.1.16.RELEASE spring-kafka版本:2.2.14.RELEASE 数据库:mybatis-plus + oracle 发现问题 一个spring-boot工程,已经通过配置spring.kafka.producer....
  • Spring事务失效的几种原因分析

    千次阅读 2021-01-18 09:56:47
    Spring事务失效的几种原因分析 1、spring的事务注解@Transactional只能放在public修饰的方法上才起作用,如果放在其他非public(private,protected)方法上,虽然不报错,但是事务不起作用 2、如果采用spring+...
  • Spring事务失效怎么办?

    2020-09-21 16:31:47
    好多小伙伴可能只是简单了解一下,遇到事务失效的情况,便会无从下手,溪源此篇文章给大家整理了一下常见Spring事务失效的场景,希望开发过程尽量避免踩坑,造成时间精力的浪费。 溪源按照最基本的使用方式以及常见...
  • Spring事务失效的各种情况 Spring 提供了两种事务管理方式: 声明式事务管理 编程式事务管理 对不同的持久层访问技术,编程式事务提供一致的事务编程风格,通过模板化的操作一致性地管理事务; 而声明式事务基于 ...
  • spring事务失效的原因与场景 Spring的事务在什么样的情况下会失效? 1底层数据库不支持事务 如MySQL的MyISAM 引擎是不支持事务操作的,如果底层使用MySQL数据库和MyISAM 引擎。那么spring事务事务管理会失效。 2没有...
  • Spring事务失效的原因主要有以下几种: 1.非public方法失效 @Transactional只有标注在public级别的方法上才能生效,对于非public方法将不会生效。这是由于Spring AOP不支持对private、protect方法进行拦截。声明 @...
  • Spring 事务失效的8大原因 目录Spring 事务失效的8大原因1、数据库引擎不支持事务2、对象没有被Spring管理3、方法不是public的4、类内部自身调用问题5、数据源没有配置事务管理器6、主动声明不支持事务7、捕获了异常...
  • spring事务失效5种大的原因 如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB。 如果使用了spring+mvc,则context:component-scan重复扫描问题可能会引起事务失败。 @...
  • Spring事务失效问题

    2021-02-23 00:26:14
    本类中,事务方法调用另外一个事务方法,事务失效 解决方法 使用代理对象调用事务方法 1.引入依赖 2.开启AspectJ动态代理:@EnableAspectJAutoProxy(exposeProxy=true) 3.使用代理对象调用(AopContext) 4.代码 &...
  • Spring事务失效的场景

    2021-03-11 11:27:26
    1.事务失效的7种情况 1)未启用spring事务管理功能 2)方法不是public类型的 3)数据源未配置事务管理器 4)自身调用问题 5)异常类型错误 6)异常被捕获 7)业务和spring事务代码必须在一个线程中 1.1未...
  • Spring事务依赖的是数据库的事务,在开发中如果没有处理好,可能会遇到事务失效的情况,本文就盘点Spring事务会失效的一些情况并给出解决方案。 Spring事务分为声明式事务和编程时事务两种。看下声明式事务。 使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,680
精华内容 10,672
关键字:

spring事务失效

spring 订阅