spring事物管理源码分析1

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

Spring实现事务的方式是通过代理+Aop来完成的,下面就以Spring实现事务的一种方式来分析这个过程。

    <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  
         abstract="true">  
       <property name="transactionManager" ref="transactionManager"/>  
       <property name="transactionAttributes">  
         <props>  
           <prop key="insert*">PROPAGATION_REQUIRED</prop>  
           <prop key="update*">PROPAGATION_REQUIRED</prop>  
           <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>  
         </props>  
       </property>  
     </bean>  
    TransactionProxyFactoryBean继承AbstractSingletonProxyFactoryBean

    @Override
        public void afterPropertiesSet() {
            if (this.target == null) {
                throw new IllegalArgumentException("Property 'target' is required");
            }
            if (this.target instanceof String) {
                throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
            }
            if (this.proxyClassLoader == null) {
                this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
            }

            ProxyFactory proxyFactory = new ProxyFactory();

            if (this.preInterceptors != null) {
                for (Object interceptor : this.preInterceptors) {
                    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
                }
            }

            // Add the main interceptor (typically an Advisor).
            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

            if (this.postInterceptors != null) {
                for (Object interceptor : this.postInterceptors) {
                    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
                }
            }

            proxyFactory.copyFrom(this);

            TargetSource targetSource = createTargetSource(this.target);
            proxyFactory.setTargetSource(targetSource);

            if (this.proxyInterfaces != null) {
                proxyFactory.setInterfaces(this.proxyInterfaces);
            }
            else if (!isProxyTargetClass()) {
                // Rely on AOP infrastructure to tell us what interfaces to proxy.
                proxyFactory.setInterfaces(
                        ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
            }

            this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
        }

    @Override
        protected Object createMainInterceptor() {
            this.transactionInterceptor.afterPropertiesSet();
            if (this.pointcut != null) {
                return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
            }
            else {
                // Rely on default pointcut.
                return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
            }
        }
    TransactionInterceptor
    public Object invoke(final MethodInvocation invocation) throws Throwable {
            // Work out the target class: may be {@code null}.
            // The TransactionAttributeSource should be passed the target class
            // as well as the method, which may be from an interface.
            Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

            // Adapt to TransactionAspectSupport's invokeWithinTransaction...
            return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
                @Override
                public Object proceedWithInvocation() throws Throwable {
                    return invocation.proceed();
                }
            });
        }
    TransactionAspectSupport
    protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
                throws Throwable {

            // If the transaction attribute is null, the method is non-transactional.
            final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
            final PlatformTransactionManager tm = determineTransactionManager(txAttr);
            final String joinpointIdentification = methodIdentification(method, targetClass);

            if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
                // Standard transaction demarcation with getTransaction and commit/rollback calls.
                TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
                Object retVal = null;
                try {
                    // This is an around advice: Invoke the next interceptor in the chain.
                    // This will normally result in a target object being invoked.
                    retVal = invocation.proceedWithInvocation();
                }
                catch (Throwable ex) {
                    // target invocation exception
                    completeTransactionAfterThrowing(txInfo, ex);
                    throw ex;
                }
                finally {
                    cleanupTransactionInfo(txInfo);
                }
                commitTransactionAfterReturning(txInfo);
                return retVal;
            }

            else {
                // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
                try {
                    Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
                            new TransactionCallback<Object>() {
                                @Override
                                public Object doInTransaction(TransactionStatus status) {
                                    TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                                    try {
                                        return invocation.proceedWithInvocation();
                                    }
                                    catch (Throwable ex) {
                                        if (txAttr.rollbackOn(ex)) {
                                            // A RuntimeException: will lead to a rollback.
                                            if (ex instanceof RuntimeException) {
                                                throw (RuntimeException) ex;
                                            }
                                            else {
                                                throw new ThrowableHolderException(ex);
                                            }
                                        }
                                        else {
                                            // A normal return value: will lead to a commit.
                                            return new ThrowableHolder(ex);
                                        }
                                    }
                                    finally {
                                        cleanupTransactionInfo(txInfo);
                                    }
                                }
                            });

                    // Check result: It might indicate a Throwable to rethrow.
                    if (result instanceof ThrowableHolder) {
                        throw ((ThrowableHolder) result).getThrowable();
                    }
                    else {
                        return result;
                    }
                }
                catch (ThrowableHolderException ex) {
                    throw ex.getCause();
                }
            }
        }
    TransactionAspectSupport
    protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
            if (txInfo != null && txInfo.hasTransaction()) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
                }
                txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
            }
        }
    AbstractPlatformTransactionManager
    @Override
        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);
        }
    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);
                    }
                    // Throw UnexpectedRollbackException if we have a global rollback-only
                    // marker but still didn't get a corresponding exception from commit.
                    if (globalRollbackOnly) {
                        throw new UnexpectedRollbackException(
                                "Transaction silently rolled back because it has been marked as rollback-only");
                    }
                }
                catch (UnexpectedRollbackException ex) {
                    // can only be caused by doCommit
                    triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
                    throw ex;
                }
                catch (TransactionException ex) {
                    // can only be caused by doCommit
                    if (isRollbackOnCommitFailure()) {
                        doRollbackOnCommitException(status, ex);
                    }
                    else {
                        triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
                    }
                    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;
                }

                // Trigger afterCommit callbacks, with an exception thrown there
                // propagated to callers but the transaction still considered as committed.
                try {
                    triggerAfterCommit(status);
                }
                finally {
                    triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
                }

            }
            finally {
                cleanupAfterCompletion(status);
            }
        }
    DataSourceTransactionManager
    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);
            }
        }

来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring事物管理源码分析1

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏