zoukankan      html  css  js  c++  java
  • Spring事务-3

    待整理

    AbstractPlatformTransactionManager

       public final TransactionStatus getTransaction(TransactionDefinition definition)
            throws TransactionException
        {
            Object transaction = doGetTransaction();
            boolean debugEnabled = logger.isDebugEnabled();
            if(definition == null)
                definition = new DefaultTransactionDefinition();
            if(isExistingTransaction(transaction))
                return handleExistingTransaction(definition, transaction, debugEnabled);
            if(definition.getTimeout() < -1)
                throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
            if(definition.getPropagationBehavior() == 2)
                throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
            if(definition.getPropagationBehavior() == 0 || definition.getPropagationBehavior() == 3 || definition.getPropagationBehavior() == 6)
            {
                SuspendedResourcesHolder suspendedResources = suspend(null);
                if(debugEnabled)
                    logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
                try
                {
                    doBegin(transaction, definition);
                }
                catch(RuntimeException ex)
                {
                    resume(null, suspendedResources);
                    throw ex;
                }
                catch(Error err)
                {
                    resume(null, suspendedResources);
                    throw err;
                }
                boolean newSynchronization = getTransactionSynchronization() != 2;
                return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            } else
            {
                boolean newSynchronization = getTransactionSynchronization() == 0;
                return newTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
            }
        }
    
        private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)
            throws TransactionException
        {
            if(definition.getPropagationBehavior() == 5)
                throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");
            if(definition.getPropagationBehavior() == 4)
            {
                if(debugEnabled)
                    logger.debug("Suspending current transaction");
                Object suspendedResources = suspend(transaction);
                boolean newSynchronization = getTransactionSynchronization() == 0;
                return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
            }
            if(definition.getPropagationBehavior() == 3)
            {
                if(debugEnabled)
                    logger.debug("Suspending current transaction, creating new transaction with name [" + definition.getName() + "]");
                SuspendedResourcesHolder suspendedResources = suspend(transaction);
                try
                {
                    doBegin(transaction, definition);
                }
                catch(RuntimeException beginEx)
                {
                    resumeAfterBeginException(transaction, suspendedResources, beginEx);
                    throw beginEx;
                }
                catch(Error beginErr)
                {
                    resumeAfterBeginException(transaction, suspendedResources, beginErr);
                    throw beginErr;
                }
                boolean newSynchronization = getTransactionSynchronization() != 2;
                return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            }
            boolean newSynchronization;
            if(definition.getPropagationBehavior() == 6)
            {
                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())
                {
                    DefaultTransactionStatus status = newTransactionStatus(definition, transaction, false, false, debugEnabled, null);
                    status.createAndHoldSavepoint();
                    return status;
                } else
                {
                    doBegin(transaction, definition);
                    newSynchronization = getTransactionSynchronization() != 2;
                    return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
                }
            }
            if(debugEnabled)
                logger.debug("Participating in existing transaction");
            if(isValidateExistingTransaction())
            {
                if(definition.getIsolationLevel() != -1)
                {
                    Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
                    if(currentIsolationLevel == null || currentIsolationLevel.intValue() != 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 ? "(unknown)" : isoConstants.toCode(currentIsolationLevel, "ISOLATION_")));
                    }
                }
                if(!definition.isReadOnly() && TransactionSynchronizationManager.isCurrentTransactionReadOnly())
                    throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is");
            }
            currentIsolationLevel = getTransactionSynchronization() == 2 ? 0 : 1;
            return newTransactionStatus(definition, transaction, false, currentIsolationLevel, debugEnabled, null);
        }
    
        protected DefaultTransactionStatus newTransactionStatus(TransactionDefinition definition, Object transaction, boolean newTransaction, boolean newSynchronization, boolean debug, Object suspendedResources)
        {
            boolean actualNewSynchronization = newSynchronization && !TransactionSynchronizationManager.isSynchronizationActive();
            if(actualNewSynchronization)
            {
                TransactionSynchronizationManager.setActualTransactionActive(transaction != null);
                TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(definition.getIsolationLevel() == -1 ? null : new Integer(definition.getIsolationLevel()));
                TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
                TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
                TransactionSynchronizationManager.initSynchronization();
            }
            return new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.isReadOnly(), debug, suspendedResources);
        }
    
        protected int determineTimeout(TransactionDefinition definition)
        {
            if(definition.getTimeout() != -1)
                return definition.getTimeout();
            else
                return defaultTimeout;
        }
    
        protected final SuspendedResourcesHolder suspend(Object transaction)
            throws TransactionException
        {
            if(TransactionSynchronizationManager.isSynchronizationActive())
            {
                List suspendedSynchronizations = doSuspendSynchronization();
                try
                {
                    Object suspendedResources = null;
                    if(transaction != null)
                        suspendedResources = doSuspend(transaction);
                    String name = TransactionSynchronizationManager.getCurrentTransactionName();
                    TransactionSynchronizationManager.setCurrentTransactionName(null);
                    boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
                    TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
                    Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
                    TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
                    boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
                    TransactionSynchronizationManager.setActualTransactionActive(false);
                    return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
                }
                catch(RuntimeException ex)
                {
                    doResumeSynchronization(suspendedSynchronizations);
                    throw ex;
                }
                catch(Error err)
                {
                    doResumeSynchronization(suspendedSynchronizations);
                    throw err;
                }
            }
            if(transaction != null)
            {
                Object suspendedResources = doSuspend(transaction);
                return new SuspendedResourcesHolder(suspendedResources);
            } else
            {
                return null;
            }
        }
    
        protected final void resume(Object transaction, SuspendedResourcesHolder resourcesHolder)
            throws TransactionException
        {
            if(resourcesHolder != null)
            {
                Object suspendedResources = resourcesHolder.suspendedResources;
                if(suspendedResources != null)
                    doResume(transaction, suspendedResources);
                List suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
                if(suspendedSynchronizations != null)
                {
                    TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
                    TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
                    TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
                    TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
                    doResumeSynchronization(suspendedSynchronizations);
                }
            }
        }
    
        private void resumeAfterBeginException(Object transaction, SuspendedResourcesHolder suspendedResources, Throwable beginEx)
        {
            String exMessage = "Inner transaction begin exception overridden by outer transaction resume exception";
            try
            {
                resume(transaction, suspendedResources);
            }
            catch(RuntimeException resumeEx)
            {
                logger.error(exMessage, beginEx);
                throw resumeEx;
            }
            catch(Error resumeErr)
            {
                logger.error(exMessage, beginEx);
                throw resumeErr;
            }
        }
    
        private List doSuspendSynchronization()
        {
            List suspendedSynchronizations = TransactionSynchronizationManager.getSynchronizations();
            for(Iterator it = suspendedSynchronizations.iterator(); it.hasNext(); ((TransactionSynchronization)it.next()).suspend());
            TransactionSynchronizationManager.clearSynchronization();
            return suspendedSynchronizations;
        }
    
        private void doResumeSynchronization(List suspendedSynchronizations)
        {
            TransactionSynchronizationManager.initSynchronization();
            TransactionSynchronization synchronization;
            for(Iterator it = suspendedSynchronizations.iterator(); it.hasNext(); TransactionSynchronizationManager.registerSynchronization(synchronization))
            {
                synchronization = (TransactionSynchronization)it.next();
                synchronization.resume();
            }
    
        }
    
        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);
                if(status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly())
                    throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");
                else
                    return;
            } else
            {
                processCommit(defStatus);
                return;
            }
        }
    
        private void processCommit(DefaultTransactionStatus status)
            throws TransactionException
        {
            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);
                }
                if(globalRollbackOnly)
                    throw new UnexpectedRollbackException("Transaction silently rolled back because it has been marked as rollback-only");
            }
            catch(UnexpectedRollbackException ex)
            {
                triggerAfterCompletion(status, 1);
                throw ex;
            }
            catch(TransactionException ex)
            {
                if(isRollbackOnCommitFailure())
                    doRollbackOnCommitException(status, ex);
                else
                    triggerAfterCompletion(status, 2);
                throw ex;
            }
            catch(RuntimeException ex)
            {
                if(!beforeCompletionInvoked)
                    triggerBeforeCompletion(status);
                doRollbackOnCommitException(status, ex);
                throw ex;
            }
            catch(Error err)
            {
                if(!beforeCompletionInvoked)
                    triggerBeforeCompletion(status);
                doRollbackOnCommitException(status, err);
                throw err;
            }
            triggerAfterCommit(status);
            triggerAfterCompletion(status, 0);
            break MISSING_BLOCK_LABEL_217;
            Exception exception;
            exception;
            triggerAfterCompletion(status, 0);
            throw exception;
            cleanupAfterCompletion(status);
            break MISSING_BLOCK_LABEL_235;
            Exception exception1;
            exception1;
            cleanupAfterCompletion(status);
            throw exception1;
        }
    
        public final void rollback(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");
            } else
            {
                DefaultTransactionStatus defStatus = (DefaultTransactionStatus)status;
                processRollback(defStatus);
                return;
            }
        }
    
        private void processRollback(DefaultTransactionStatus status)
        {
            try
            {
                triggerBeforeCompletion(status);
                if(status.hasSavepoint())
                {
                    if(status.isDebug())
                        logger.debug("Rolling back transaction to savepoint");
                    status.rollbackToHeldSavepoint();
                } else
                if(status.isNewTransaction())
                {
                    if(status.isDebug())
                        logger.debug("Initiating transaction rollback");
                    doRollback(status);
                } else
                if(status.hasTransaction())
                {
                    if(status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure())
                    {
                        if(status.isDebug())
                            logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
                        doSetRollbackOnly(status);
                    } else
                    if(status.isDebug())
                        logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
                } else
                {
                    logger.debug("Should roll back transaction but cannot - no transaction available");
                }
            }
            catch(RuntimeException ex)
            {
                triggerAfterCompletion(status, 2);
                throw ex;
            }
            catch(Error err)
            {
                triggerAfterCompletion(status, 2);
                throw err;
            }
            triggerAfterCompletion(status, 1);
            cleanupAfterCompletion(status);
            break MISSING_BLOCK_LABEL_197;
            Exception exception;
            exception;
            cleanupAfterCompletion(status);
            throw exception;
        }
    
        private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex)
            throws TransactionException
        {
            try
            {
                if(status.isNewTransaction())
                {
                    if(status.isDebug())
                        logger.debug("Initiating transaction rollback after commit exception", ex);
                    doRollback(status);
                } else
                if(status.hasTransaction() && isGlobalRollbackOnParticipationFailure())
                {
                    if(status.isDebug())
                        logger.debug("Marking existing transaction as rollback-only after commit exception", ex);
                    doSetRollbackOnly(status);
                }
            }
            catch(RuntimeException rbex)
            {
                logger.error("Commit exception overridden by rollback exception", ex);
                triggerAfterCompletion(status, 2);
                throw rbex;
            }
            catch(Error rberr)
            {
                logger.error("Commit exception overridden by rollback exception", ex);
                triggerAfterCompletion(status, 2);
                throw rberr;
            }
            triggerAfterCompletion(status, 1);
        }
    
        protected final void triggerBeforeCommit(DefaultTransactionStatus status)
        {
            if(status.isNewSynchronization())
            {
                if(status.isDebug())
                    logger.trace("Triggering beforeCommit synchronization");
                TransactionSynchronizationUtils.triggerBeforeCommit(status.isReadOnly());
            }
        }
    
        protected final void triggerBeforeCompletion(DefaultTransactionStatus status)
        {
            if(status.isNewSynchronization())
            {
                if(status.isDebug())
                    logger.trace("Triggering beforeCompletion synchronization");
                TransactionSynchronizationUtils.triggerBeforeCompletion();
            }
        }
    
        private void triggerAfterCommit(DefaultTransactionStatus status)
        {
            if(status.isNewSynchronization())
            {
                if(status.isDebug())
                    logger.trace("Triggering afterCommit synchronization");
                TransactionSynchronizationUtils.triggerAfterCommit();
            }
        }
    
        private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus)
        {
            if(status.isNewSynchronization())
            {
                List synchronizations = TransactionSynchronizationManager.getSynchronizations();
                if(!status.hasTransaction() || status.isNewTransaction())
                {
                    if(status.isDebug())
                        logger.trace("Triggering afterCompletion synchronization");
                    invokeAfterCompletion(synchronizations, completionStatus);
                } else
                {
                    registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
                }
            }
        }
    
        protected final void invokeAfterCompletion(List synchronizations, int completionStatus)
        {
            TransactionSynchronizationUtils.invokeAfterCompletion(synchronizations, completionStatus);
        }
    
        private void cleanupAfterCompletion(DefaultTransactionStatus status)
        {
            status.setCompleted();
            if(status.isNewSynchronization())
                TransactionSynchronizationManager.clear();
            if(status.isNewTransaction())
                doCleanupAfterCompletion(status.getTransaction());
            if(status.getSuspendedResources() != null)
            {
                if(status.isDebug())
                    logger.debug("Resuming suspended transaction");
                resume(status.getTransaction(), (SuspendedResourcesHolder)status.getSuspendedResources());
            }
        }

    DataSourceTransactionManager

    protected Object doGetTransaction()
        {
            DataSourceTransactionObject txObject = new DataSourceTransactionObject();
            txObject.setSavepointAllowed(isNestedTransactionAllowed());
            ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(dataSource);
            txObject.setConnectionHolder(conHolder, false);
            return txObject;
        }
    
        protected boolean isExistingTransaction(Object transaction)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
            return txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive();
        }
    
        protected void doBegin(Object transaction, TransactionDefinition definition)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
            Connection con = null;
            try
            {
                if(txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction())
                {
                    Connection newCon = dataSource.getConnection();
                    if(logger.isDebugEnabled())
                        logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
                    txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
                }
                txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
                con = txObject.getConnectionHolder().getConnection();
                Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
                txObject.setPreviousIsolationLevel(previousIsolationLevel);
                if(con.getAutoCommit())
                {
                    txObject.setMustRestoreAutoCommit(true);
                    if(logger.isDebugEnabled())
                        logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
                    con.setAutoCommit(false);
                }
                txObject.getConnectionHolder().setTransactionActive(true);
                int timeout = determineTimeout(definition);
                if(timeout != -1)
                    txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
                if(txObject.isNewConnectionHolder())
                    TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
            }
            catch(SQLException ex)
            {
                DataSourceUtils.releaseConnection(con, dataSource);
                throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
            }
        }
    
        protected Object doSuspend(Object transaction)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
            txObject.setConnectionHolder(null);
            ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.unbindResource(dataSource);
            return conHolder;
        }
    
        protected void doResume(Object transaction, Object suspendedResources)
        {
            ConnectionHolder conHolder = (ConnectionHolder)suspendedResources;
            TransactionSynchronizationManager.bindResource(dataSource, conHolder);
        }
    
        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);
            }
        }
    
        protected void doRollback(DefaultTransactionStatus status)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)status.getTransaction();
            Connection con = txObject.getConnectionHolder().getConnection();
            if(status.isDebug())
                logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
            try
            {
                con.rollback();
            }
            catch(SQLException ex)
            {
                throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
            }
        }
    
        protected void doSetRollbackOnly(DefaultTransactionStatus status)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)status.getTransaction();
            if(status.isDebug())
                logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only");
            txObject.setRollbackOnly();
        }
    
        protected void doCleanupAfterCompletion(Object transaction)
        {
            DataSourceTransactionObject txObject = (DataSourceTransactionObject)transaction;
            if(txObject.isNewConnectionHolder())
                TransactionSynchronizationManager.unbindResource(dataSource);
            Connection con = txObject.getConnectionHolder().getConnection();
            try
            {
                if(txObject.isMustRestoreAutoCommit())
                    con.setAutoCommit(true);
                DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
            }
            catch(Throwable ex)
            {
                logger.debug("Could not reset JDBC Connection after transaction", ex);
            }
            if(txObject.isNewConnectionHolder())
            {
                if(logger.isDebugEnabled())
                    logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
                DataSourceUtils.releaseConnection(con, dataSource);
            }
            txObject.getConnectionHolder().clear();
        }
    
        private DataSource dataSource;
    }

     HibernateTransactionManager

  • 相关阅读:
    软件工程第四次作业
    软件工程第三次作业-------(李利思 岳庆)
    软件工程第二次作业
    《软件工程》第一次作业
    构建之法书评
    个人阅读作业三
    对MSF八个原则的思考
    个人阅读作业2 软工方法论无用?
    代码复审
    结对编程总结 1175 1176
  • 原文地址:https://www.cnblogs.com/wangjianbg/p/3449521.html
Copyright © 2011-2022 走看看