logo头像

学如逆水行舟,不进则退!!!

文章目录

spring事务失效了,怎么办

本文于354天之前发表,文中内容可能已经过时。

前言

  • 在spring中为了保证数据的准确性。spring接入了数据库的事务。
  • 事务的特性呢无非就是ACID 。 A=Atomicity(原子性); C=Consistency(一致性);I=isolation(隔离性); D=Durability(持久性)
  • 而spring针对数据的四种隔离级别实现spring的事务传播属性。这里不做细化分讲

问题描述

  • 在Spring中配置事务也很简单我们只要在启动类上添加相关注解并在AOP中配置切面拦截我们定义的方法或者直接通过Transactional 来实现事务的配置。
  • 但是在我的一个方法里居然发现事务失效了。
@Transactional
public ResultInfo getPayInfo(Long id) {
        return this.getPaymentInfo(id);
    }
  • 我们在getPayInfo这个方法中调用了同级的另外一个方法getPaymentInfo。 两个方法我们都配置的事务切实两个不同的事务。
  • 但是我在执行的时候发现最终效果并不是如此。在外部的方法getPayInfo事务是正常的。但是通过this.getPaymentInfo这个方法内部的事务根本没有生效。我在这个方法里特意写错进行异常报错。但是里面已经执行的数据并没有发生回滚。因为外部和内部是两个不同的事务所以外部本身就不收影响。
  • 关于如何配置外部和内部事务不同这里也不赘述了。就是配置spring的传播属性。

问题分析

  • 有问题是好事说明我们还有进步的空间。我们仔细想想事务是如何实现的。
  • 其实spring是没有事务。spring的事务其实就是数据库的事务。spring只是负责转发
  • 而spring实现事务就是保证使用的是同一个数据库connection 。 这个就是通过ThreadLocal实现的
  • 而剩下connection的连接后就交由数据库管理了。事务的管理spring是基于aop进行拦截的。但是我们上述代码是通过this调用方法的。我们知道spring中的bean实际上不是真正的对象而是基于原生对象产生的代理对象。
  • 只有代理对象才能通过spring的aop拦截。而this是直接通过内部进行调用的不会走aop的那么这里的事务就会失效。

总结

  • 事务依赖于aop 。 this调用直接避开了aop 。所以没有了事务。
  • 知其然不知其所以然。还是需要努力学习的。
上一篇
坚持原创技术分享,您的支持将鼓励我继续创作!

评论系统未开启,无法评论!