Spring 中事务不生效的原因

1 篇文章 0 订阅

事务在我们应用程序上面是一个很重要的功能点,事务能保证程序在同一处理链路上的sql执行要么全部成功,要么全部失败,不会出现执行一半sql成功,另一半sql执行不成功,是数据库中数据一致性的保证;

那我们平时在spring框架中开发时候会不会遇到过spring中明明加了@Transactional 注解或者配置了其他事务管理的方式事务还是不生效的情况呢;

首先我们要知道spring事务是怎么实现的,spring中的事务如果你在方法、类上加上@Transactional注解就代表这个类被spring aop所代理了,事务是通过spring中aop的切面编程特性来完成事务的开启、提交、回滚,所以事务生效的前提是在调用过程中是以代理的方式调用;

那什么时候会使事务失效,以下看看这几种情况:

1. 首先看看是不是数据库引擎的问题;在mysql数据库中,myisam引擎是不支持事务的,是数据库层级上面的不支持;innodb引擎才支持;

2. 被调用的方法的访问级别是否是public;这时候把思路放到AOP上,spring中很多东西的实现都是依靠AOP,本质上也是依靠代理来实现。事务在spring中的实现其实就是生成bean对象的代理对象。在bean进行创建出实话时, 如果是有事务注解的方法,就会被进行增强,最终形成代理类。在spring中,有两种动态代理的方式,一种是jdk,它是将原始对象放入代理对象内部,通过调用内含的原始对象来实现原始的业务逻辑,这是一种装饰器模式; 而另一种是cglib,它是通过生成原始对象的子类,子类复写父类的方法,从而实现对父类的增强。jdk中,如果是private的方法,显然是无法访问的,而在cglib中,也是同样,private方法也无法访问。于是原始对象的业务逻辑就丢失了,那么怎么进行增强呢?于是这个问题实际在于,被aop增强的方法都应该是public的,而不能是private的;

3. spring中只对运行时异常(RuntimeException)的异常对事务进行回滚;

4. spring框架中是否配置了开启事务;spring中<tx:annotation-driven />、 @EnableTransactionManagement

5. 代码中事务是否在同一线程内;不在同一线程内无法生效,原因参考aop;

6. 是否是以代理的方式去调用方法;例如下面的情况是不生效的(我遇到过,当时很苦恼):

 像这种add方法里面直接调用了本类的有事务注解的方法,事务也是不生效的;应该在调用add2方法时使用代理的方式去调用,这样才会触发aop中事务的管理;如:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值