spring的事物实现

Spring的事物主要有三个接口

PlatformTransactionManager、

根据TransactionDefinition配置的事物信息创建事物

TransactionDefinition

主要描述控制具体事物行为的属性,比如事物隔离级别,超时时间,传播行为等

TransactionStatus

代表了事物具体的运行状态

Spring事物的具体实现是交给底层持久化框架实现的,如下:

hibernate3  HibernateTransactionManger

jdbc           DataSourceTransactionManger

类图简单如下:

PlatformTransactionManager

            |

            |

AbstractPlatformTransactionManager

|                                               |

|                                               |

HibernateTransactionManger       DataSourceTransactionManger

PlatformTransactionManager只是简单定义了事物的公共方法

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;

}

通过模板方法模式调用底层事物管理器的实现,比如commit方法

    public final void commit(TransactionStatus status) throws TransactionException {
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(
                    "Transaction is already completed - do not call commit or rollback more than once per transaction");
        }

        DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
        if (defStatus.isLocalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Transactional code has requested rollback");
            }
            processRollback(defStatus);
            return;
        }
        if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
            if (defStatus.isDebug()) {
                logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
            }
            processRollback(defStatus);
            // Throw UnexpectedRollbackException only at outermost transaction boundary
            // or if explicitly asked to.
            if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                throw new UnexpectedRollbackException(
                        "Transaction rolled back because it has been marked as rollback-only");
            }
            return;
        }

        processCommit(defStatus);
    }

processCommit方法会调用具体事物管理器的具体实现,比如jdb的事物管理器

    @Override
    protected void doCommit(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        if (status.isDebug()) {
            logger.debug("Committing JDBC transaction on Connection [" + con + "]");
        }
        try {
            con.commit();
        }
        catch (SQLException ex) {
            throw new TransactionSystemException("Could not commit JDBC transaction", ex);
        }
    }

通常我们一个方法里面有可能有多个事物操作,spring是怎样保证,是在同一个事物下进行的呢?

spring为此定义了事物同步管理器

spring将jdbc的Connection hibernate的session等统称为资源

要实现操作是在同一个事物下进行的,则要保证处理操作的线程是用的同一个资源操作的,比如jdbc的Connection,如果方法内几个操作是用的

同一个Connection进行操作的,就可以统一的进行事物的控制。

那么怎么样才能保证线程拿到的是统一的资源呢?

spring使用了threadlocal进行实现

事物管理器的类如下:

public abstract class TransactionSynchronizationManager {

    private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);
        //用于保存每个线程对connection或者session的资源
    private static final ThreadLocal<Map<Object, Object>> resources =
            new NamedThreadLocal<Map<Object, Object>>("Transactional resources");

    private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
            new NamedThreadLocal<Set<TransactionSynchronization>>("Transaction synchronizations");
        //用于保存每个事物线程对应事物名称
    private static final ThreadLocal<String> currentTransactionName =
            new NamedThreadLocal<String>("Current transaction name");

    private static final ThreadLocal<Boolean> currentTransactionReadOnly =
            new NamedThreadLocal<Boolean>("Current transaction read-only status");

    private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
            new NamedThreadLocal<Integer>("Current transaction isolation level");

    private static final ThreadLocal<Boolean> actualTransactionActive =
            new NamedThreadLocal<Boolean>("Actual transaction active");

...........................

}

为此spring提供了一套获取资源的公共类,比如

jdbc mybits  对应DataSourceUtils

hibernate3对应SessionFastoryUtils等

这样当底层事物管理器操作资源的时候,会通过事物资源管理器操作事物,因为事物资源管理器获取或者操作的资源都是在当前线程内(threadlocal实现),所以能够保证是同一个,这样spring就实现了事物的控制。

原文地址:https://www.cnblogs.com/zpitbolg/p/5094752.html