博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring---transaction(4)---源代码分析(事务的状态TransactionStatus)
阅读量:4941 次
发布时间:2019-06-11

本文共 9479 字,大约阅读时间需要 31 分钟。

写在前面

  TransactionStatus表示一个具体的事务状态(这里应用到了Java的一个多继承,接口允许多继承

  TransactionStatus它继承了SavepointManager接口,SavepointManager是对事务中上述保存点功能的封装(Spring利用保存点功能实现了事务的嵌套功能。后面会详细说明)

public interface SavepointManager {    Object createSavepoint() throws TransactionException;    void rollbackToSavepoint(Object savepoint) throws TransactionException;    void releaseSavepoint(Object savepoint) throws TransactionException;}
public interface TransactionStatus extends SavepointManager, Flushable {    //是否是一个新的事物    boolean isNewTransaction();    //是否有保存点    boolean hasSavepoint();    void setRollbackOnly();    //是否已被标记为回滚    boolean isRollbackOnly();     @Override    void flush();    boolean isCompleted();}

 

 

DefaultTransactionStatus

常用的TransactionStatus接口实现为DefaultTransactionStatus:

public class DefaultTransactionStatus extends AbstractTransactionStatus {    private final Object transaction;    private final boolean newTransaction;    private final boolean newSynchronization;    private final boolean readOnly;    private final boolean debug;    private final Object suspendedResources;}

  目前jdbc事务是通过Connection来实现事务的,Hibernate是通过它自己定义的Transaction来实现的,所以各家的事务都不同,所以Spring只能以Object transaction的形式来表示各家的事务,事务的回滚和提交等操作都会最终委托给上述Object transaction来完成。

  Object transaction的职责就是提交回滚事务,这个transaction的选择可能如下:

    • DataSourceTransactionObject
    • HibernateTransactionObject
    • JpaTransactionObject

  详细信息分别如下:

  • DataSourceTransactionObject:

    我们使用了dataSource来获取连接,要想实现事务功能,必然需要使用Connection,所以它中肯定有一个Connection来执行事务的操作。DataSourceTransactionObject中有一个ConnectionHolder,它封装了一个Connection。

  • HibernateTransactionObject:

    我们使用了hibenrate,此时要想实现事务功能,必然需要通过hibernate自己定义的Transaction来实现。

HibernateTransactionObject中含有一个SessionHolder,和上面的ConnectionHolder一样,它封装了一个Session,有了Session,我们就可以通过Session来产生一个Hibernate的Transaction,从而实现事务操作。

 

 

DefaultTransactionStatus的获取

  DefaultTransactionStatus的获取是事务管理器的方法,这里的实现是AbstractPlatformTransactionManager提供的模板方法

  在获取Object transaction之后,先进行判断,是否是已存在的事务。因为这个Object transaction的获取过程就是直接从线程绑定的获取的,可能当前线程已经存在事务

@Override    public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
     //获取相应的Object transaction Object transaction = doGetTransaction();     //就是依据和当前线程绑定的ConnectionHolder中是否已存在事务(也是依据和当前线程绑定的SessionHolder是否已存在事务) if (isExistingTransaction(transaction)) {
       //如果是已存在事务:则需要对事务的传播属性进行处理,如下即上述截图中的的handleExistingTransaction方法: return handleExistingTransaction(definition, transaction, debugEnabled); }      ...}

 

  如果是已存在事务:则需要对事务的传播属性进行处理,如下即上述截图中的的handleExistingTransaction方法

private TransactionStatus handleExistingTransaction(            TransactionDefinition definition, Object transaction, boolean debugEnabled)            throws TransactionException {     // PROPAGATION_NEVER:不允许存在事务,如果存在抛出异常        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {            throw new IllegalTransactionStateException(                    "Existing transaction found for transaction marked with propagation 'never'");        }     // PROPAGATION_NOT_SUPPORTED:不支持事务,如果存在事务,则需将事务挂起,保存起来,当执行完成之后,需要将挂起的事务继续恢复        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {            if (debugEnabled) {                logger.debug("Suspending current transaction");            }            Object suspendedResources = suspend(transaction);            boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);            return prepareTransactionStatus(                    definition, null, false, newSynchronization, debugEnabled, suspendedResources);        }     //PROPAGATION_REQUIRES_NEW:开启一个新的事务,如果当前存在事务则把当前事务挂起来        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {            if (debugEnabled) {                logger.debug("Suspending current transaction, creating new transaction with name [" +                        definition.getName() + "]");            }            SuspendedResourcesHolder suspendedResources = suspend(transaction);            try {                boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);                DefaultTransactionStatus status = newTransactionStatus(                        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);          //可以看到,创建新的事务,就会调用doBegin(transaction, definition);方法,将事务开启。                doBegin(transaction, definition);                prepareSynchronization(status, definition);                return status;            }            catch (RuntimeException beginEx) {                resumeAfterBeginException(transaction, suspendedResources, beginEx);                throw beginEx;            }            catch (Error beginErr) {                resumeAfterBeginException(transaction, suspendedResources, beginErr);                throw beginErr;            }        }        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {            if (!isNestedTransactionAllowed()) {                throw new NestedTransactionNotSupportedException(                        "Transaction manager does not allow nested transactions by default - " +                        "specify 'nestedTransactionAllowed' property with value 'true'");            }            if (debugEnabled) {                logger.debug("Creating nested transaction with name [" + definition.getName() + "]");            }            if (useSavepointForNestedTransaction()) {                // Create savepoint within existing Spring-managed transaction,                // through the SavepointManager API implemented by TransactionStatus.                // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.                DefaultTransactionStatus status =                        prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);                status.createAndHoldSavepoint();                return status;            }            else {                // Nested transaction through nested begin and commit/rollback calls.                // Usually only for JTA: Spring synchronization might get activated here                // in case of a pre-existing JTA transaction.                boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);                DefaultTransactionStatus status = newTransactionStatus(                        definition, transaction, true, newSynchronization, debugEnabled, null);                doBegin(transaction, definition);                prepareSynchronization(status, definition);                return status;            }        }        // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.      //PROPAGATION_SUPPORTS 和 PROPAGATION_REQUIRED 如果当前存在事务,则仍旧使用该事物          if (debugEnabled) {            logger.debug("Participating in existing transaction");        }        if (isValidateExistingTransaction()) {            if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {                Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();                if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {                    Constants isoConstants = DefaultTransactionDefinition.constants;                    throw new IllegalTransactionStateException("Participating transaction with definition [" +                            definition + "] specifies isolation level which is incompatible with existing transaction: " +                            (currentIsolationLevel != null ?                                    isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :                                    "(unknown)"));                }            }            if (!definition.isReadOnly()) {                if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {                    throw new IllegalTransactionStateException("Participating transaction with definition [" +                            definition + "] is not marked as read-only but existing transaction is");                }            }        }        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);        return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);    }

  

  事务的挂起

  对于DataSourceTransactionManager来说,事务的挂起,就是把当前线程关联的ConnectionHolder解除绑定、同理事务的恢复就是把上述ConnectionHolder再重新绑定到当前线程,继续执行该事务

@Override    protected Object doSuspend(Object transaction) {        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;        txObject.setConnectionHolder(null);         //解除绑定dataSource, conHolder 至 TransactionSynchronizationManager        ConnectionHolder conHolder = (ConnectionHolder)                TransactionSynchronizationManager.unbindResource(this.dataSource);        return conHolder;    }    @Override    protected void doResume(Object transaction, Object suspendedResources) {        ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;       //重新绑定dataSource, conHolder 至 TransactionSynchronizationManager        TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);    }

 

转载于:https://www.cnblogs.com/chihirotan/p/6760317.html

你可能感兴趣的文章
Java实现简单的计算器(原创)
查看>>
Java实现的日历(原创)
查看>>
sql server 2005学习笔记之触发器简介(一)
查看>>
Flex的Tree全部展开收缩,ji展开选中单个节点
查看>>
CMMI与Agile敏捷开发比较之一:两者的本质区别
查看>>
如何打造139团队(不同层次人员的选择与培养,大型研发团队,大型敏捷开发团队)...
查看>>
SSCE(SQL Server Compact Edition)适合哪些应用场景
查看>>
VS 2010 SP1 and SQL CE :ScottGu's Blog
查看>>
J2EE的13种核心技术简介
查看>>
JQuery怎么知道一个元素是否隐藏或显示How do you test if something is hidden in jQuery?
查看>>
Java发送Http请求,解析html返回
查看>>
将截断字符串或二进制数据。
查看>>
C#编码简单性之泛型篇(如何编写简短的C#代码,随时更新)
查看>>
Windows7 Home高级 64 中文版 + TortoiseSVN 64 英文版 + SVN Server 32 英文版安装过程
查看>>
IT人员及程序员怎样学好英语(关于如何利用极其有限的时间和条件学好英文)...
查看>>
在Visual Studio的Server Explorer中怎样修改表名
查看>>
[视频]怎样提升asp.net mvc 软件的性能 - 微软免费视频Improving ASP.NET MVC Application Performance...
查看>>
CMMI与Agile敏捷开发比较之二:需求管理篇(兼谈用敏捷实现和满足CMMI的ReqM过程域)...
查看>>
asp.net MVC中怎样让LINQ Designer自动生成的类从别的类继承并调用其基类构造器?...
查看>>
asp.net mvc 如何在执行完某任务后返回原来页面
查看>>