本文转自“天河聊技术”微信公众号spring
说在前面数据库
@Transactional实现,接着上篇文章继续微信
正文ide
事务回滚源码解析this
上次解析到这个方法org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction的这一行debug
执行事务方法code
retVal = invocation.proceedWithInvocation();
catch (Throwable ex) { // target invocation exception 执行业务方法异常 completeTransactionAfterThrowing(txInfo, ex); throw ex; }
进入到这个方法orm
org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing事务
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) { if (txInfo != null && txInfo.getTransactionStatus() != null) { if (logger.isTraceEnabled()) { logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "] after exception: " + ex); } // 有指定的异常回滚,异常类型是检查异常或者是非检查异常,非检查性异常自动回滚 if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) { try { // 事务回滚 txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); } catch (TransactionSystemException ex2) { logger.error("Application exception overridden by rollback exception", ex); ex2.initApplicationException(ex); throw ex2; } catch (RuntimeException | Error ex2) { logger.error("Application exception overridden by rollback exception", ex); throw ex2; } } else { // We don't roll back on this exception. // Will still roll back if TransactionStatus.isRollbackOnly() is true. try { txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); } catch (TransactionSystemException ex2) { logger.error("Application exception overridden by commit exception", ex); ex2.initApplicationException(ex); throw ex2; } catch (RuntimeException | Error ex2) { logger.error("Application exception overridden by commit exception", ex); throw ex2; } } } }
事务回滚 txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
进入到这个方法ip
org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback
@Override 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"); } DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; // 执行事务回滚 processRollback(defStatus, false); }
private void processRollback(DefaultTransactionStatus status, boolean unexpected) { try { boolean unexpectedRollback = unexpected; 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 { // Participating in larger transaction参与更大的交易 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"); } // Unexpected rollback only matters here if we're asked to fail early若是咱们被要求提早失败,那么意外的回滚就很重要了。 if (!isFailEarlyOnGlobalRollbackOnly()) { unexpectedRollback = false; } } } catch (RuntimeException | Error ex) { triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); throw ex; } triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); // Raise UnexpectedRollbackException if we had a global rollback-only marker若是咱们有一个仅用于全局回滚的标记,那么就会引起unexpected tedrollbackexception if (unexpectedRollback) { throw new UnexpectedRollbackException( "Transaction rolled back because it has been marked as rollback-only"); } } finally { cleanupAfterCompletion(status); } }
事务状态回退到回滚点 status.rollbackToHeldSavepoint();
public void rollbackToHeldSavepoint() throws TransactionException { Object savepoint = getSavepoint(); if (savepoint == null) { throw new TransactionUsageException( "Cannot roll back to savepoint - no savepoint associated with current transaction"); } // 事务回滚到事务回滚点 getSavepointManager().rollbackToSavepoint(savepoint); // 释放事务回滚点 getSavepointManager().releaseSavepoint(savepoint); setSavepoint(null); }
返回到这个方法
org.springframework.transaction.support.AbstractPlatformTransactionManager#processRollback这行
事务回滚 doRollback(status);
@Override 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); } }
事务提交源码解析
返回到这个方法org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing这行
事务提交
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
进入到这个方法org.springframework.transaction.support.AbstractPlatformTransactionManager#commit
@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, false); return; } // 全局事务回滚 if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) { if (defStatus.isDebug()) { logger.debug("Global transaction is marked as rollback-only but transactional code requested commit"); } // 事务回滚 processRollback(defStatus, true); return; } // 事务提交 processCommit(defStatus); }
// 事务提交 processCommit(defStatus);
private void processCommit(DefaultTransactionStatus status) throws TransactionException { try { boolean beforeCompletionInvoked = false; try { boolean unexpectedRollback = false; // 准备提交 prepareForCommit(status); // 出发提交以前回调 triggerBeforeCommit(status); triggerBeforeCompletion(status); beforeCompletionInvoked = true; if (status.hasSavepoint()) { if (status.isDebug()) { logger.debug("Releasing transaction savepoint"); } unexpectedRollback = status.isGlobalRollbackOnly(); status.releaseHeldSavepoint(); } else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction commit"); } unexpectedRollback = status.isGlobalRollbackOnly(); // 事务提交 doCommit(status); } else if (isFailEarlyOnGlobalRollbackOnly()) { unexpectedRollback = status.isGlobalRollbackOnly(); } // Throw UnexpectedRollbackException if we have a global rollback-only若是咱们只进行全局回滚,那么将抛出unexpected tedrollbackexception // marker but still didn't get a corresponding exception from commit.可是仍然没有从commit获得相应的异常。 if (unexpectedRollback) { throw new UnexpectedRollbackException( "Transaction silently rolled back because it has been marked as rollback-only"); } } catch (UnexpectedRollbackException ex) { // can only be caused by doCommit只能由doCommit引发吗 triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); throw ex; } catch (TransactionException ex) { // can only be caused by doCommit只能由doCommit引发吗 if (isRollbackOnCommitFailure()) { doRollbackOnCommitException(status, ex); } else { triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); } throw ex; } catch (RuntimeException | Error ex) { if (!beforeCompletionInvoked) { triggerBeforeCompletion(status); } doRollbackOnCommitException(status, ex); throw ex; } // Trigger afterCommit callbacks, with an exception thrown there触发afterCommit回调,并在其中抛出一个异常 // propagated to callers but the transaction still considered as committed.传播到调用者,但事务仍然被认为是提交的。 try { triggerAfterCommit(status); } finally { triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED); } } finally { cleanupAfterCompletion(status); } }
说到最后
本次解析仅表明我的看法,仅供参考。