likes
comments
collection
share

SpringAOP之事务核心底层原理深度剖析

作者站长头像
站长
· 阅读数 34

写作背景 之前在极客时间上学习了玩转 《Spring 全家桶》和小马哥的《spring aop 编程思想》 最近闲暇了,把之前的笔记和知识点串起来整理一下自己也搞个专栏。 Spring AOP是Spring框架中的一个重要组件,它提供了一种基于代理模式的技术,可以在目标对象的方法执行前、执行后或抛出异常时,自动地执行某些处理逻辑。Spring AOP的其中一个重要应用场景是事务处理,它可以通过在方法执行前创建事务,在方法执行后提交或回滚事务,从而保证了数据的一致性和完整性。

Spring的事务管理模块

Spring AOP的事务处理主要依赖于Spring的事务管理模块,其中核心的底层原理如下:

1. 事务管理器(TransactionManager

Spring通过TransactionManager统一管理所有的事务资源。TransactionManager可以管理多种不同的事务资源,例如JDBC、Hibernate、JPA等。Spring框架为TransactionManager提供了多种实现方式,例如DataSourceTransactionManagerHibernateTransactionManager、JpaTransactionManager等。

2. 事务定义(TransactionDefinition)

事务定义是一个接口,它定义了事务的隔离级别、超时时间、只读标志等属性。Spring框架为TransactionDefinition提供了多种实现方式,例如DefaultTransactionDefinition、RuleBasedTransactionDefinition等。

3. 事务状态(TransactionStatus)

事务状态是一个接口,它定义了事务的当前状态和控制事务的方法,例如提交、回滚等。Spring框架为TransactionStatus提供了多种实现方式,例如DefaultTransactionStatus、JdbcTransactionObjectSupport等。

4. 事务拦截器(TransactionInterceptor)

事务拦截器是AOP中的一个切面,它用于拦截被@Transactional注解标记的方法,并在方法执行前后创建和提交事务。在创建事务时,事务拦截器会通过TransactionManager获取事务资源,并使用TransactionDefinition定义事务属性。在方法执行后,如果方法执行成功,事务拦截器会调用TransactionStatus的commit()方法提交事务;如果方法执行失败,事务拦截器会调用TransactionStatus的rollback()方法回滚事务。

Spring 事务处理依赖于Spring的事务管理模块,其中事务管理器、事务定义和事务状态是核心的底层组件,事务拦截器是AOP中的切面,用于拦截被@Transactional注解标记的方法并创建和提交事务。通过这些组件的协作,Spring AOP实现了高效、安全、灵活的事务处理。

源码解析

Spring AOP的事务处理涉及到多个核心组件和实现细节,下面将结合源码解析其中的一些关键部分。

1. 事务管理器(TransactionManager

Spring框架为TransactionManager提供了多种实现方式,其中最常用的是DataSourceTransactionManager。DataSourceTransactionManager是基于JDBC的事务管理器,它使用JDBC的Connection对象来管理事务。下面是DataSourceTransactionManager的源码:源码解析见代码注释

// DataSourceTransactionManager继承了AbstractPlatformTransactionManager类,
// 它实现了doGetTransaction、doBegin、doCommit、doRollback和doCleanupAfterCompletion等方法
// TransactionSynchronizationManager是Spring框架提供的一个线程绑定的事务同步管理器,用于管理事务状态和资源。
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager {
  
  private DataSource dataSource;
  
  public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
  }
  // doGetTransaction方法用于创建TransactionObject对象,
  // TransactionObject是Spring框架定义的一个事务对象,用于保存事务状态。
  protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
  }
  //  doBegin方法用于开始事务,它会获取一个Connection对象,并设置事务的隔离级别和超时时间等属性。
  protected void doBegin(Object transaction, TransactionDefinition definition) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;
    try {
      con = dataSource.getConnection();
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
        con.setTransactionIsolation(definition.getIsolationLevel());
      }
      txObject.setConnectionHolder(new ConnectionHolder(con), true);
      if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
        txObject.getConnectionHolder().setTimeoutInSeconds(definition.getTimeout());
      }
      logger.debug("Began JDBC transaction on connection [" + con + "]");
    }
    catch (SQLException ex) {
      throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
    }
  }
  // doCommit方法用于提交事务,它会将事务中的所有操作提交到数据库中。
  protected void doCommit(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    try {
      con.commit();
    }
    catch (SQLException ex) {
      throw new TransactionSystemException("Could not commit JDBC transaction", ex);
    }
  }
  // doRollback方法用于回滚事务,它会将事务中的所有操作回滚到之前的状态
  protected void doRollback(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    try {
      con.rollback();
    }
    catch (SQLException ex) {
      throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
    }
  }
  // doCleanupAfterCompletion方法用于清理事务资源,它会释放Connection对象,
  // 并从TransactionSynchronizationManager中移除TransactionObject对象。

  protected void doCleanupAfterCompletion(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    ConnectionHolder conHolder = txObject.getConnectionHolder();
    conHolder.release();
    //TransactionSynchronizationManager是Spring框架提供的一个线程绑定的事务同步管理器,用于管理事务状态和资源。
    TransactionSynchronizationManager.unbindResource(dataSource);
  }
  
  private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
    
    public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {
      super.setConnectionHolder(connectionHolder, newConnectionHolder);
    }
    
    public Connection getConnection() {
      return getConnectionHolder().getConnection();
    }
    
  }
  
}
  1. doGetTransaction方法用于创建TransactionObject对象,TransactionObject是Spring框架定义的一个事务对象,用于保存事务状态。
  2. doBegin方法用于开始事务,它会获取一个Connection对象,并设置事务的隔离级别和超时时间等属性。doCommit方法用于提交事务,它会将事务中的所有操作提交到数据库中。
  3. doRollback方法用于回滚事务,它会将事务中的所有操作回滚到之前的状态。
  4. doCleanupAfterCompletion方法用于清理事务资源,它会释放Connection对象,并从TransactionSynchronizationManager中移除TransactionObject对象。

2. 事务定义(TransactionDefinition)

TransactionDefinition是Spring框架定义的一个接口,用于定义事务的属性,包括传播行为、隔离级别、超时时间等。下面是TransactionDefinition的源码: 这块没有啥讲的,大家一看就懂。

public interface TransactionDefinition {
  
  int PROPAGATION_REQUIRED = 0;
  int PROPAGATION_SUPPORTS = 1;
  int PROPAGATION_MANDATORY = 2;
  int PROPAGATION_REQUIRES_NEW = 3;
  int PROPAGATION_NOT_SUPPORTED = 4;
  int PROPAGATION_NEVER = 5;
  int PROPAGATION_N
  int PROPAGATION_NESTED = 6;
  
  int ISOLATION_DEFAULT = -1;
  int ISOLATION_READ_UNCOMMITTED = 1;
  int ISOLATION_READ_COMMITTED = 2;
  int ISOLATION_REPEATABLE_READ = 4;
  int ISOLATION_SERIALIZABLE = 8;
  
  int TIMEOUT_DEFAULT = -1;
  
  int getPropagationBehavior();
  
  int getIsolationLevel();
  
  int getTimeout();
  
  boolean isReadOnly();
  
}

这块没啥讲的,大家一看就懂, TransactionDefinition定义了PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_NEW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER和PROPAGATION_NESTED等传播行为常量,以及ISOLATION_DEFAULT、ISOLATION_READ_UNCOMMITTED、ISOLATION_READ_COMMITTED、ISOLATION_REPEATABLE_READ和ISOLATION_SERIALIZABLE等隔离级别常量。TransactionDefinition还定义了getPropagationBehavior、getIsolationLevel、getTimeout和isReadOnly等方法,用于获取事务的传播行为、隔离级别、超时时间和只读属性。

3. 事务增强器(TransactionInterceptor)

TransactionInterceptor是Spring框架提供的一个AOP增强器,它可以将事务管理器和事务定义应用到被增强的方法中,实现事务管理的自动化。下面是TransactionInterceptor的源码:这块如果要详细讲解也是挺复杂的,我准备单独写一篇文章详细解析。

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
    public TransactionInterceptor() {
    }

    public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
        this.setTransactionManager(ptm);
        this.setTransactionAttributes(attributes);
    }

    public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
        this.setTransactionManager(ptm);
        this.setTransactionAttributeSource(tas);
    }

    @Nullable
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
        Method var10001 = invocation.getMethod();
        invocation.getClass();
        return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(this.getTransactionManagerBeanName());
        oos.writeObject(this.getTransactionManager());
        oos.writeObject(this.getTransactionAttributeSource());
        oos.writeObject(this.getBeanFactory());
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject();
        this.setTransactionManagerBeanName((String)ois.readObject());
        this.setTransactionManager((PlatformTransactionManager)ois.readObject());
        this.setTransactionAttributeSource((TransactionAttributeSource)ois.readObject());
        this.setBeanFactory((BeanFactory)ois.readObject());
    }
}

TransactionInterceptor实现了MethodInterceptor接口,它通过invoke方法拦截被增强的方法,并调用invokeWithinTransaction方法来执行事务管理。invokeWithinTransaction方法会获取当前事务状态,并根据事务定义和传播行为来决定是否开启新的事务或加入已有的事务。如果事务已经存在,则直接执行被增强的方法,否则会先开启新的事务,执行被增强的方法,然后提交或回滚事务。

4. 声明式事务管理(Declarative Transaction Management

Spring框架还提供了一种声明式事务管理的方式,它可以通过配置文件或注解来定义事务管理规则,实现对方法的事务管理。下面是使用注解方式配置声明式事务管理的示例:

@Service
@Transactional
public class UserServiceImpl implements UserService {
  
  @Autowired
  private UserDao userDao;
  
  public void addUser(User user) {
    userDao.addUser(user);
  }
  
}

通过在类上加上@Transactional注解,就可以将类中的所有方法都纳入到事务管理中。在这个例子中,每个方法都会在一个新的事务中执行,如果出现异常则会回滚事务。可以通过@Transactional注解的属性来定义事务的传播行为、隔离级别、超时时间和只读属性等。

转载自:https://juejin.cn/post/7220613829587288120
评论
请登录