在之前的文章Spring事务源码解析(二)获取增强中,我们分析了Spring事务的实现是基于AOP实现的,还分析了增强BeanFactoryTransactionAttributeSourceAdvisor中的相关内容。而这个增强中包含一个拦截器TransactionInterceptor,代理的实现就是基于这个拦截器
现在来看一下这个拦截器的代码

TransactionInterceptor

invoke() 方法中调用了 TransactionInterceptor 父类的方法 invokeWithinTransaction() ,处理方法的调用

  1. public Object invoke(final MethodInvocation invocation) throws Throwable {
  2. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
  3. // 往下看
  4. return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
  5. }
  6. protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
  7. final InvocationCallback invocation) throws Throwable {
  8. TransactionAttributeSource tas = getTransactionAttributeSource();
  9. // 获取事务属性
  10. final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
  11. //【这里获取到了用户注入的DataSourceTransactionManager】
  12. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
  13. //方法标识,例如usersService.testTransaction
  14. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  15. //声明式事务
  16. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  17. // 1.创建TransactionInfo
  18. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
  19. Object retVal = null;
  20. try {
  21. // 2. 调用执行链
  22. retVal = invocation.proceedWithInvocation();
  23. }
  24. catch (Throwable ex) {
  25. // 3. 异常回滚
  26. completeTransactionAfterThrowing(txInfo, ex);
  27. throw ex;
  28. }
  29. finally {
  30. //4. 清除事务信息
  31. cleanupTransactionInfo(txInfo);
  32. }
  33. //5 提交事务
  34. commitTransactionAfterReturning(txInfo);
  35. return retVal;
  36. }
  37. else {
  38. //编程式事务处理
  39. final ThrowableHolder throwableHolder = new ThrowableHolder();
  40. try {
  41. Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
  42. TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  43. try {
  44. return invocation.proceedWithInvocation();
  45. }
  46. catch (Throwable ex) {
  47. if (txAttr.rollbackOn(ex)) {
  48. if (ex instanceof RuntimeException) {
  49. throw (RuntimeException) ex;
  50. }
  51. else {
  52. throw new ThrowableHolderException(ex);
  53. }
  54. }
  55. else {
  56. throwableHolder.throwable = ex;
  57. return null;
  58. }
  59. }
  60. finally {
  61. cleanupTransactionInfo(txInfo);
  62. }
  63. });
  64. if (throwableHolder.throwable != null) {
  65. throw throwableHolder.throwable;
  66. }
  67. return result;
  68. }
  69. catch (ThrowableHolderException ex) {
  70. throw ex.getCause();
  71. }
  72. catch (TransactionSystemException ex2) {
  73. if (throwableHolder.throwable != null) {
  74. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  75. ex2.initApplicationException(throwableHolder.throwable);
  76. }
  77. throw ex2;
  78. }
  79. catch (Throwable ex2) {
  80. if (throwableHolder.throwable != null) {
  81. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  82. }
  83. throw ex2;
  84. }
  85. }
  86. }

DataSourceTransactionManager

txManager的注入在查找对应的TransactionManager中,最终会寻找PlatformTransactionManager类型的类,用户之前在JDBCConfig配置时配置了一个DataSourceTransactionManager,它是PlatformTransactionManager的实现类
image.png

由于咱们经常使用的就是声明式事务,所以接下来的解析也是基于声明式事务来的

创建事务

  1. protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
  2. @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
  3. //如果事务没有指定名称则使用方法标识
  4. if (txAttr != null && txAttr.getName() == null) {
  5. txAttr = new DelegatingTransactionAttribute(txAttr) {
  6. @Override
  7. public String getName() {
  8. return joinpointIdentification;
  9. }
  10. };
  11. }
  12. TransactionStatus status = null;
  13. if (txAttr != null) {
  14. if (tm != null) {
  15. //1. 创建事务
  16. status = tm.getTransaction(txAttr);
  17. }
  18. else {
  19. if (logger.isDebugEnabled()) {
  20. logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
  21. "] because no transaction manager has been configured");
  22. }
  23. }
  24. }
  25. //2.构建事务信息
  26. return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  27. }

获取事务

  1. public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
  2. //1. 获取事务【这里调用的使用的对应的DataSourcetTransactionManager,上方tm赋值的】
  3. Object transaction = doGetTransaction();
  4. boolean debugEnabled = logger.isDebugEnabled();
  5. if (definition == null) {
  6. definition = new DefaultTransactionDefinition();
  7. }
  8. //2. 判断当前线程是否存在事务
  9. if (isExistingTransaction(transaction)) {
  10. //【存在事务则使用嵌套事务处理】
  11. return handleExistingTransaction(definition, transaction, debugEnabled);
  12. }
  13. // 事务超时
  14. if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
  15. throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
  16. }
  17. // 如果当前没有事务,但是事务的传播行为被定义为PROPAGATION_MANDATORY,则抛出异常
  18. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
  19. throw new IllegalTransactionStateException(
  20. "No existing transaction found for transaction marked with propagation 'mandatory'");
  21. }//当事务的传播行为需要新建事务时的处理
  22. else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
  23. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
  24. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  25. SuspendedResourcesHolder suspendedResources = suspend(null);
  26. if (debugEnabled) {
  27. logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
  28. }
  29. try {
  30. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  31. DefaultTransactionStatus status = newTransactionStatus(
  32. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  33. //3. 【准备事务】
  34. doBegin(transaction, definition);
  35. //4. 记录事务状态
  36. prepareSynchronization(status, definition);
  37. return status;
  38. }
  39. catch (RuntimeException | Error ex) {
  40. resume(null, suspendedResources);
  41. throw ex;
  42. }
  43. }
  44. else {
  45. // 创建空事务
  46. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
  47. logger.warn("Custom isolation level specified but no actual transaction initiated; " +
  48. "isolation level will effectively be ignored: " + definition);
  49. }
  50. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  51. return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
  52. }
  53. }

整个获取事务的过程还是包含多个步骤的,其中doBegin比较值得聊一聊

  1. protected void doBegin(Object transaction, TransactionDefinition definition) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  3. Connection con = null;
  4. try {
  5. if (!txObject.hasConnectionHolder() ||
  6. txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
  7. Connection newCon = obtainDataSource().getConnection();
  8. if (logger.isDebugEnabled()) {
  9. logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
  10. }
  11. txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
  12. }
  13. txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
  14. //获取当前数据库连接
  15. con = txObject.getConnectionHolder().getConnection();
  16. //获取隔离级别
  17. Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
  18. txObject.setPreviousIsolationLevel(previousIsolationLevel);
  19. // 设置自动提交
  20. if (con.getAutoCommit()) {
  21. txObject.setMustRestoreAutoCommit(true);
  22. if (logger.isDebugEnabled()) {
  23. logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
  24. }
  25. con.setAutoCommit(false);
  26. }
  27. prepareTransactionalConnection(con, definition);
  28. //设置当前线程存在事务的标示
  29. txObject.getConnectionHolder().setTransactionActive(true);
  30. //设置超时时间
  31. int timeout = determineTimeout(definition);
  32. if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
  33. txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
  34. }
  35. // 将连接绑定到当前线程(里面有ThreadLocal)
  36. if (txObject.isNewConnectionHolder()) {
  37. TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
  38. }
  39. }
  40. catch (Throwable ex) {
  41. if (txObject.isNewConnectionHolder()) {
  42. DataSourceUtils.releaseConnection(con, obtainDataSource());
  43. txObject.setConnectionHolder(null, false);
  44. }
  45. throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
  46. }
  47. }

嵌套事务处理

至于记录事务状态这里先不说,先看一下已存在的事务是如何处理的

  1. private TransactionStatus handleExistingTransaction(
  2. TransactionDefinition definition, Object transaction, boolean debugEnabled)
  3. throws TransactionException {
  4. //判断传播行为是否需要存在事务
  5. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
  6. throw new IllegalTransactionStateException(
  7. "Existing transaction found for transaction marked with propagation 'never'");
  8. }
  9. //不开启事务
  10. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
  11. if (debugEnabled) {
  12. logger.debug("Suspending current transaction");
  13. }
  14. Object suspendedResources = suspend(transaction);
  15. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  16. return prepareTransactionStatus(
  17. definition, null, false, newSynchronization, debugEnabled, suspendedResources);
  18. }
  19. //总是新建事务
  20. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
  21. if (debugEnabled) {
  22. logger.debug("Suspending current transaction, creating new transaction with name [" +
  23. definition.getName() + "]");
  24. }
  25. SuspendedResourcesHolder suspendedResources = suspend(transaction);
  26. try {
  27. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  28. DefaultTransactionStatus status = newTransactionStatus(
  29. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  30. doBegin(transaction, definition);
  31. prepareSynchronization(status, definition);
  32. return status;
  33. }
  34. catch (RuntimeException | Error beginEx) {
  35. resumeAfterBeginException(transaction, suspendedResources, beginEx);
  36. throw beginEx;
  37. }
  38. }
  39. //嵌套事务
  40. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  41. if (!isNestedTransactionAllowed()) {
  42. throw new NestedTransactionNotSupportedException(
  43. "Transaction manager does not allow nested transactions by default - " +
  44. "specify 'nestedTransactionAllowed' property with value 'true'");
  45. }
  46. if (debugEnabled) {
  47. logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
  48. }
  49. if (useSavepointForNestedTransaction()) {
  50. // Create savepoint within existing Spring-managed transaction,
  51. // through the SavepointManager API implemented by TransactionStatus.
  52. // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
  53. DefaultTransactionStatus status =
  54. prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
  55. status.createAndHoldSavepoint();
  56. return status;
  57. }
  58. else {
  59. // Nested transaction through nested begin and commit/rollback calls.
  60. // Usually only for JTA: Spring synchronization might get activated here
  61. // in case of a pre-existing JTA transaction.
  62. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  63. DefaultTransactionStatus status = newTransactionStatus(
  64. definition, transaction, true, newSynchronization, debugEnabled, null);
  65. doBegin(transaction, definition);
  66. prepareSynchronization(status, definition);
  67. return status;
  68. }
  69. }
  70. // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
  71. if (debugEnabled) {
  72. logger.debug("Participating in existing transaction");
  73. }
  74. if (isValidateExistingTransaction()) {
  75. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
  76. Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
  77. if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
  78. Constants isoConstants = DefaultTransactionDefinition.constants;
  79. throw new IllegalTransactionStateException("Participating transaction with definition [" +
  80. definition + "] specifies isolation level which is incompatible with existing transaction: " +
  81. (currentIsolationLevel != null ?
  82. isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
  83. "(unknown)"));
  84. }
  85. }
  86. if (!definition.isReadOnly()) {
  87. if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
  88. throw new IllegalTransactionStateException("Participating transaction with definition [" +
  89. definition + "] is not marked as read-only but existing transaction is");
  90. }
  91. }
  92. }
  93. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  94. return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
  95. }

可以看到记录事务状态是最后一步了,嵌套和不嵌套都会走这里

  1. protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
  2. if (status.isNewSynchronization()) {
  3. TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
  4. TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
  5. definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
  6. definition.getIsolationLevel() : null);
  7. TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
  8. TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
  9. TransactionSynchronizationManager.initSynchronization();
  10. }
  11. }

构建事务信息

  1. protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
  2. @Nullable TransactionAttribute txAttr, String joinpointIdentification,
  3. @Nullable TransactionStatus status) {
  4. TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
  5. if (txAttr != null)
  6. if (logger.isTraceEnabled()) {
  7. logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
  8. }
  9. // 记录事务状态
  10. txInfo.newTransactionStatus(status);
  11. }
  12. else {
  13. if (logger.isTraceEnabled())
  14. logger.trace("Don't need to create transaction for [" + joinpointIdentification +
  15. "]: This method isn't transactional.");
  16. }
  17. txInfo.bindToThread();
  18. return txInfo;
  19. }

事务回滚

可以知道事务回滚是进入这个方法, invokeWithinTransaction()completeTransactionAfterThrowing()

  1. protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
  2. //是否存在事务
  3. if (txInfo != null && txInfo.getTransactionStatus() != null) {
  4. if (logger.isTraceEnabled()) {
  5. logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
  6. "] after exception: " + ex);
  7. }
  8. //是否满足回滚条件,比如是否运行时异常等
  9. if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
  10. try {
  11. //【回滚处理】
  12. txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
  13. }
  14. catch (TransactionSystemException ex2) {
  15. logger.error("Application exception overridden by rollback exception", ex);
  16. ex2.initApplicationException(ex);
  17. throw ex2;
  18. }
  19. catch (RuntimeException | Error ex2) {
  20. logger.error("Application exception overridden by rollback exception", ex);
  21. throw ex2;
  22. }
  23. }
  24. else {
  25. //不满足回滚条件时同样提交
  26. try {
  27. txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
  28. }
  29. catch (TransactionSystemException ex2) {
  30. logger.error("Application exception overridden by commit exception", ex);
  31. ex2.initApplicationException(ex);
  32. throw ex2;
  33. }
  34. catch (RuntimeException | Error ex2) {
  35. logger.error("Application exception overridden by commit exception", ex);
  36. throw ex2;
  37. }
  38. }
  39. }
  40. }

回滚的逻辑

  1. public final void rollback(TransactionStatus status) throws TransactionException {
  2. //如果事务完成了就不能回滚
  3. if (status.isCompleted()) {
  4. throw new IllegalTransactionStateException(
  5. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  6. }
  7. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  8. processRollback(defStatus, false);
  9. }
  10. private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
  11. try {
  12. boolean unexpectedRollback = unexpected;
  13. try {
  14. //扩展点
  15. triggerBeforeCompletion(status);
  16. //如果有保存点
  17. if (status.hasSavepoint()) {
  18. if (status.isDebug()) {
  19. logger.debug("Rolling back transaction to savepoint");
  20. }
  21. //推到保存点
  22. status.rollbackToHeldSavepoint();
  23. }
  24. else if (status.isNewTransaction()) {
  25. if (status.isDebug()) {
  26. logger.debug("Initiating transaction rollback");
  27. }//如果当前事务为独立事务则直接回退
  28. doRollback(status);
  29. }
  30. else {
  31. // Participating in larger transaction
  32. if (status.hasTransaction()) {
  33. if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
  34. if (status.isDebug()) {
  35. logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
  36. }
  37. //不是独立事务标记状态
  38. doSetRollbackOnly(status);
  39. }
  40. else {
  41. if (status.isDebug()) {
  42. logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
  43. }
  44. }
  45. }
  46. else {
  47. logger.debug("Should roll back transaction but cannot - no transaction available");
  48. }
  49. // Unexpected rollback only matters here if we're asked to fail early
  50. if (!isFailEarlyOnGlobalRollbackOnly()) {
  51. unexpectedRollback = false;
  52. }
  53. }
  54. }
  55. catch (RuntimeException | Error ex) {
  56. triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
  57. throw ex;
  58. }
  59. //扩展点
  60. triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
  61. // Raise UnexpectedRollbackException if we had a global rollback-only marker
  62. if (unexpectedRollback) {
  63. throw new UnexpectedRollbackException(
  64. "Transaction rolled back because it has been marked as rollback-only");
  65. }
  66. }
  67. finally {
  68. //清理资源
  69. cleanupAfterCompletion(status);
  70. }
  71. }

而真的的回滚逻辑则是利用JDBC的回滚逻辑实现的

  1. protected void doRollback(DefaultTransactionStatus status) {
  2. DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
  3. Connection con = txObject.getConnectionHolder().getConnection();
  4. if (status.isDebug()) {
  5. this.logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
  6. }
  7. try {
  8. con.rollback();
  9. } catch (SQLException var5) {
  10. throw new TransactionSystemException("Could not roll back JDBC transaction", var5);
  11. }
  12. }

事务提交

invokeWithinTransaction()commitTransactionAfterReturning()

  1. protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
  2. if (txInfo != null && txInfo.getTransactionStatus() != null) {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
  5. }
  6. txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
  7. }
  8. }
  9. public final void commit(TransactionStatus status) throws TransactionException {
  10. //如果事务已经完成
  11. if (status.isCompleted()) {
  12. throw new IllegalTransactionStateException(
  13. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  14. }
  15. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  16. //如果事务设置了回滚标记则直接回滚
  17. if (defStatus.isLocalRollbackOnly()) {
  18. if (defStatus.isDebug()) {
  19. logger.debug("Transactional code has requested rollback");
  20. }
  21. processRollback(defStatus, false);
  22. return;
  23. }
  24. if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
  25. if (defStatus.isDebug()) {
  26. logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
  27. }
  28. processRollback(defStatus, true);
  29. return;
  30. }
  31. //提交事务
  32. processCommit(defStatus);
  33. }
  34. private void processCommit(DefaultTransactionStatus status) throws TransactionException {
  35. try {
  36. boolean beforeCompletionInvoked = false;
  37. try {
  38. boolean unexpectedRollback = false;
  39. //扩展点的相关调用
  40. prepareForCommit(status);
  41. triggerBeforeCommit(status);
  42. triggerBeforeCompletion(status);
  43. beforeCompletionInvoked = true;
  44. if (status.hasSavepoint()) {
  45. if (status.isDebug()) {
  46. logger.debug("Releasing transaction savepoint");
  47. }
  48. unexpectedRollback = status.isGlobalRollbackOnly();
  49. //清除保存点信息
  50. status.releaseHeldSavepoint();
  51. }
  52. else if (status.isNewTransaction()) {
  53. if (status.isDebug()) {
  54. logger.debug("Initiating transaction commit");
  55. }
  56. unexpectedRollback = status.isGlobalRollbackOnly();
  57. //提交事务,同样这里也是调用的JDBC的方法实现的
  58. doCommit(status);
  59. }
  60. else if (isFailEarlyOnGlobalRollbackOnly()) {
  61. unexpectedRollback = status.isGlobalRollbackOnly();
  62. }
  63. // Throw UnexpectedRollbackException if we have a global rollback-only
  64. // marker but still didn't get a corresponding exception from commit.
  65. if (unexpectedRollback) {
  66. throw new UnexpectedRollbackException(
  67. "Transaction silently rolled back because it has been marked as rollback-only");
  68. }
  69. }
  70. catch (UnexpectedRollbackException ex) {
  71. // can only be caused by doCommit
  72. triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
  73. throw ex;
  74. }
  75. catch (TransactionException ex) {
  76. // can only be caused by doCommit
  77. if (isRollbackOnCommitFailure()) {
  78. doRollbackOnCommitException(status, ex);
  79. }
  80. else {
  81. triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
  82. }
  83. throw ex;
  84. }
  85. catch (RuntimeException | Error ex) {
  86. if (!beforeCompletionInvoked) {
  87. triggerBeforeCompletion(status);
  88. }
  89. doRollbackOnCommitException(status, ex);
  90. throw ex;
  91. }
  92. // Trigger afterCommit callbacks, with an exception thrown there
  93. // propagated to callers but the transaction still considered as committed.
  94. try {
  95. triggerAfterCommit(status);
  96. }
  97. finally {
  98. triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
  99. }
  100. }
  101. finally {
  102. cleanupAfterCompletion(status);
  103. }
  104. }