Spring的事物管理框架源码分析

前言

  • 现在Spring框架在Web项目中应用的越来越广泛,Spring框架与其它框架的融合设计的也特别的到位,譬如说Spring与Hibernate结合以后共同处理事务的框架,可是说设计思想非常巧妙,值得让人学习,前几篇博客小编发表了一篇Spring的声明式事务处理,今天由小编带领着大家一块来研究一下Spring的事务管理框架吧!

事务管理机制分析

  • 1、由程序告诉spring容器,什么样的目标方法采用什么样的事务策略,譬如说,在Service层中,一个Query开头的查询方法,它采用什么样的事务隔离机制,是采取只读事务还是读写事务等等。
  • 2、事务的处理:由spring容器来完成的,实际上,Spring容器只是配置好了,但是来完成具体事务操作的还是具体的TransactionManager,下面会介绍。
  • 3、程序员:此时程序员只需要关心CRDU操作,不比关心事务了,因为等一切配置做好以后,程序要只要按照规则做就行了,其实,具体的规则就是事务声明中的method配置。这个配置小编在Spring的声明式事务处理机制已经详细列出。小编给出一小段代码。
<tx:advice transaction-manager="transactionManager" id="tx">
        <tx:attributes>
        <!-- name:目标方法的范围 isolation:事物的隔离机制 propagation:传播属性,解决事物的嵌套问题 read-only:true(只读事物) false(读写事物) -->
            <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" />
        </tx:attributes>
    </tx:advice>

简单框架类图

《Spring的事物管理框架源码分析》

类图分析

从类图中我们可以看出,Spring框架平台给出一个PlatformTransactionManager借口,此接口有三个方法,一个是getTransaction(),一个是commit(), 最后一个是rollback(),然后让一个AbstractPlatformTransactionManager抽象类来实现此接口,最后分别让DataSourceTransactionManager、HibernateTransactionManager 和JdoTransactionManager来继承上面那个抽象类。

源码分析

PlatformTransactionManager(事物管理平台接口)


package org.springframework.transaction;

public interface PlatformTransactionManager {


    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;

}

此接口提供三个方法,由AbstractPlatformTransactionManager来实现,由于此抽象类方法甚多,我只贴出几个关键方法吧!

AbstractPlatformTransactionManager



public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable { ...... ...... private void processCommit(DefaultTransactionStatus status) throws TransactionException { try { boolean beforeCompletionInvoked = false; try { prepareForCommit(status); triggerBeforeCommit(status); triggerBeforeCompletion(status); beforeCompletionInvoked = true; boolean globalRollbackOnly = false; if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { globalRollbackOnly = status.isGlobalRollbackOnly(); } if (status.hasSavepoint()) { if (status.isDebug()) { logger.debug("Releasing transaction savepoint"); } status.releaseHeldSavepoint(); } else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction commit"); } doCommit(status);//此方法是抽象方法,谁继承,谁实现,本片文章中介绍HibernateTransactionManager类来实现此方法 } ...... ...... } ...... ...... } public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Object transaction = doGetTransaction(); //此方法是抽象方法,谁继承,谁实现,本片文章中介绍HibernateTransactionManager类来实现此方法 ...... ...... ...... } } 

HibernateTransactionManager

public class HibernateTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {

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


    protected Object doGetTransaction() {

        SessionHolder sessionHolder =
                (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());//
        if (sessionHolder != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Found thread-bound Session [" +
                        SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");
            }
            txObject.setSessionHolder(sessionHolder);
        }
        else if (this.hibernateManagedSession) {
            try {
                Session session = getSessionFactory().getCurrentSession();得到Session,为开启事务做准备。。。。
                if (logger.isDebugEnabled()) {
                    logger.debug("Found Hibernate-managed Session [" +
                            SessionFactoryUtils.toString(session) + "] for Spring-managed transaction");
                }
                txObject.setExistingSession(session);
            }
            catch (HibernateException ex) {
                throw new DataAccessResourceFailureException(
                        "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);
            }
        }

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

        return txObject;
    }


    protected void doCommit(DefaultTransactionStatus status) {
        HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
        if (status.isDebug()) {
            logger.debug("Committing Hibernate transaction on Session [" +
                    SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");
        }
        try {
            txObject.getSessionHolder().getTransaction().commit();//事务再此提交
        }
        catch (org.hibernate.TransactionException ex) {
            ......
        }
        catch (HibernateException ex) {
            ......
        }
    }

    ......
    ......
    ......
}

小结

  • spring在调用具体的事务管理器之前做了一些准备工作,譬如提前设置事务的读写策略,而这些事务策略是公共的东西,是写在spring的配置文件中的,所以这些公共内容的处理由抽象类中去做,然后在抽象类中留一些让具体事务管理器实现的抽象方法,像doCommit()、doRollback()等。Spring的这种设计思想确实巧妙,值得我们学习。
    原文作者:Spring MVC
    原文地址: https://blog.csdn.net/zhoukun1008/article/details/53946152
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞