Spring 事务原理总结三

今天这篇文章,我想梳理一下Spring事务用到的几个核心组件。这些核心组件是我们理解Spring事务原理的基础。通过它们我们可以体会学习一下Spring设计者设计Spring事务时的基本思路。这些组件是:TransactionInfo、TransactionStatus、TransactionManager、TransactionAttribute、TransactionAttributeSource、ReactiveTransactionSupport等等。

首先让我们一起看一下TransactionInfo类。它是一个位于TransactionAspectSupport类中的内部类(这个类是上一节介绍的TransactionInterceptor的父类,TransactionInterceptor是一个增强类,用于对那些需要事务的方法进行增强)。TransactionInfo类的源码如下:

protected static final class TransactionInfo {
    @Nullable
    private final PlatformTransactionManager transactionManager;
    @Nullable
    private final TransactionAttribute transactionAttribute;
    private final String joinpointIdentification;
    @Nullable
    private TransactionStatus transactionStatus;
    @Nullable
    private TransactionInfo oldTransactionInfo;
    public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,
          @Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {
       this.transactionManager = transactionManager;
       this.transactionAttribute = transactionAttribute;
       this.joinpointIdentification = joinpointIdentification;
    }
    public PlatformTransactionManager getTransactionManager() {
       Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
       return this.transactionManager;
    }
    @Nullable
    public TransactionAttribute getTransactionAttribute() {
       return this.transactionAttribute;
    }
    /**
     * Return a String representation of this joinpoint (usually a Method call)
     * for use in logging.
     */
    public String getJoinpointIdentification() {
       return this.joinpointIdentification;
    }
    public void newTransactionStatus(@Nullable TransactionStatus status) {
       this.transactionStatus = status;
    }
    @Nullable
    public TransactionStatus getTransactionStatus() {
       return this.transactionStatus;
    }
    /**
     * Return whether a transaction was created by this aspect,
     * or whether we just have a placeholder to keep ThreadLocal stack integrity.
     */
    public boolean hasTransaction() {
       return (this.transactionStatus != null);
    }
    private void bindToThread() {
       // Expose current TransactionStatus, preserving any existing TransactionStatus
       // for restoration after this transaction is complete.
       this.oldTransactionInfo = transactionInfoHolder.get();
       transactionInfoHolder.set(this);
    }
    private void restoreThreadLocalStatus() {
       // Use stack to restore old transaction TransactionInfo.
       // Will be null if none was set.
       transactionInfoHolder.set(this.oldTransactionInfo);
    }
    @Override
    public String toString() {
       return (this.transactionAttribute != null ? this.transactionAttribute.toString() : "No transaction");
    }
}

通过源码不难看出TransactionInfo是一个最终类,也没有继承或实现其他接口或类,其中的属性有PlatformTransactionManager、TransactionAttribute、TransactionStatus、TransactionInfo(通过其变量名可以知道其代表的是老事务。还记得《Spring事务原理总结一》这篇文章中提到的事务传播属性吗?其中提到的REQUIRES_NEW可能就是通过这个属性来实现的)等。

然后让我们再一起看一下TransactionStatus接口,其又继承了SavepointManager、Flushable、TransactionExecution等接口。下面是该接口的源码:

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {

    /**
     * Return whether this transaction internally carries a savepoint,
     * that is, has been created as nested transaction based on a savepoint.
     * <p>This method is mainly here for diagnostic purposes, alongside
     * {@link #isNewTransaction()}. For programmatic handling of custom
     * savepoints, use the operations provided by {@link SavepointManager}.
     * <p>The default implementation returns {@code false}.
     * @see #isNewTransaction()
     * @see #createSavepoint()
     * @see #rollbackToSavepoint(Object)
     * @see #releaseSavepoint(Object)
     */
    default boolean hasSavepoint() {
       return false;
    }

    /**
     * Flush the underlying session to the datastore, if applicable:
     * for example, all affected Hibernate/JPA sessions.
     * <p>This is effectively just a hint and may be a no-op if the underlying
     * transaction manager does not have a flush concept. A flush signal may
     * get applied to the primary resource or to transaction synchronizations,
     * depending on the underlying resource.
     * <p>The default implementation is empty, considering flush as a no-op.
     */
    @Override
    default void flush() {
    }

}

下图则是TransactionStatus接口的继承体系:

接着来让我们来看一下TransactionAttribute接口,该位于org.springframework.transaction.interceptor包中,先来看一下其源码:

public interface TransactionAttribute extends TransactionDefinition {

    /**
     * Return a qualifier value associated with this transaction attribute.
     * <p>This may be used for choosing a corresponding transaction manager
     * to process this specific transaction.
     * @since 3.0
     */
    @Nullable
    String getQualifier();

    /**
     * Return labels associated with this transaction attribute.
     * <p>This may be used for applying specific transactional behavior
     * or follow a purely descriptive nature.
     * @since 5.3
     */
    Collection<String> getLabels();

    /**
     * Should we roll back on the given exception?
     * @param ex the exception to evaluate
     * @return whether to perform a rollback or not
     */
    boolean rollbackOn(Throwable ex);

}

下图是TransactionAttribute这个接口的继承体系(这里面我们中断关注RuleBasedTransactionAttribute这个类,第一次跟踪事务的执行代码时实际类型为RuleBasedTransactionAttribute):

最后再来看一下PlatformTransactionManager这个接口,该接口继承了TransactionManager接口,其有4个实现类,分别为AbstractPlatformTransactionManager、DataSourceTransactionManager、JdbcTransactionManager、JtaTransactionManager。个人理解它是一个管理接口。先看一下它的继承体系:

至此我们梳理了Spring事务涉及到的一些基本组件及其体系结构(这只是个人粗浅的认知,如果不全,还望各位大佬指正)。至于这些组件的作用,我们将在下一篇博客中逐一梳理。

猜你喜欢

转载自blog.csdn.net/java_lover20111106/article/details/136017131