Spring Boot 事务@Transactional的实现原理

       @Transactional 涉及到两个方面,一个是数据的持久化,第二个是数据库的事务。关于持久化以及事务不做赘述。

在持久化中涉及到了实体管理器EntityManager类,该类通过@PersistenceContext进行注解,标识只注入一次实体管理器,但是因为EntityManager是一个interface,所以它的注入是通过感知上下文内容进行注入的,因此是存在的问题的,所以需要进行一层代理,这层代理一般是用SharedEntityManagerInvocationHandler。

        @Transactional的具体工作原理可从以下三个方面进行把握,EntityManager的代理,Transactional层面,Transactional管理器层面。

        Transactional层面:它的执行包含执行前的决策,和执行后的处理,其中执行前是通过Transactional管理器决定如何进行的,这一步主要是决定新的事务怎么处理。执行后是看结果是否进行commit或者进行roll back。

        Transactional管理器层面:决定是否创建一个新的事务,是否创建一个新的实力管理器。如果决定要创建一个新的事务,那么需要进行以下操作。创建一个新的事务,并且将这个新事务与当前已有的事务进行绑定,然后从数据库连接池中拿取一个线程,并将该线程与当前事务进行绑定。 

    这里需要注意的是如何决定是否创建一个新的事务,那么就要从事务配置的传播行为TransactionDefinition说起:

     (这一部分参考自https://www.cnblogs.com/yepei/p/4716112.html

  • Spring的默认是PROPAGATION_REQUIRED。如果当前存在事务就加入该事务,如果没有就创建一个。
  • PROPAGATION_REQUIRES_NEW。创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
  • PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

EntityManager代理层面 通过代理唤醒EntityManager

猜你喜欢

转载自blog.csdn.net/lee_master/article/details/103893585