当前位置:   article > 正文

Spring 源码学习笔记(六) Spring事务_methodinvocation.getthis

methodinvocation.getthis

个人学习Spring源码系列 Spring事务

 


(一)事务增强器

TransactionInterceptor支撑着整个事务功能的架构,调用该类是从invoke方法开始。

  1. public Object invoke(MethodInvocation invocation) throws Throwable {
  2. // Work out the target class: may be {@code null}.
  3. // The TransactionAttributeSource should be passed the target class
  4. // as well as the method, which may be from an interface.
  5. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
  6. // Adapt to TransactionAspectSupport's invokeWithinTransaction...
  7. return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
  8. @Override
  9. @Nullable
  10. public Object proceedWithInvocation() throws Throwable {
  11. return invocation.proceed();
  12. }
  13. @Override
  14. public Object getTarget() {
  15. return invocation.getThis();
  16. }
  17. @Override
  18. public Object[] getArguments() {
  19. return invocation.getArguments();
  20. }
  21. });
  22. }
  1. protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
  2. final InvocationCallback invocation) throws Throwable {
  3. // If the transaction attribute is null, the method is non-transactional.
  4. TransactionAttributeSource tas = getTransactionAttributeSource();
  5. //1.获取对应事务的属性
  6. final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
  7. //2.获取beanFactory中的TransactionManager
  8. final TransactionManager tm = determineTransactionManager(txAttr);
  9. if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
  10. boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
  11. boolean hasSuspendingFlowReturnType = isSuspendingFunction &&
  12. COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName());
  13. if (isSuspendingFunction && !(invocation instanceof CoroutinesInvocationCallback)) {
  14. throw new IllegalStateException("Coroutines invocation not supported: " + method);
  15. }
  16. CoroutinesInvocationCallback corInv = (isSuspendingFunction ? (CoroutinesInvocationCallback) invocation : null);
  17. ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
  18. Class<?> reactiveType =
  19. (isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType());
  20. ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
  21. if (adapter == null) {
  22. throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
  23. method.getReturnType());
  24. }
  25. return new ReactiveTransactionSupport(adapter);
  26. });
  27. InvocationCallback callback = invocation;
  28. if (corInv != null) {
  29. callback = () -> CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
  30. }
  31. Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager) tm);
  32. if (corInv != null) {
  33. Publisher<?> pr = (Publisher<?>) result;
  34. return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow(pr) :
  35. KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation()));
  36. }
  37. return result;
  38. }
  39. PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
  40. //构造方法唯一标识(类.方法)
  41. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  42. //3.声明式事务处理
  43. if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
  44. // Standard transaction demarcation with getTransaction and commit/rollback calls.
  45. //4.创建TransactionInfo
  46. TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
  47. Object retVal;
  48. try {
  49. // This is an around advice: Invoke the next interceptor in the chain.
  50. // This will normally result in a target object being invoked.
  51. //5.执行被增强方法
  52. retVal = invocation.proceedWithInvocation();
  53. }
  54. catch (Throwable ex) {
  55. // target invocation exception
  56. //6.异常回滚
  57. completeTransactionAfterThrowing(txInfo, ex);
  58. throw ex;
  59. }
  60. finally {
  61. //清除信息
  62. cleanupTransactionInfo(txInfo);
  63. }
  64. if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
  65. // Set rollback-only in case of Vavr failure matching our rollback rules...
  66. TransactionStatus status = txInfo.getTransactionStatus();
  67. if (status != null && txAttr != null) {
  68. retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
  69. }
  70. }
  71. //提交事务
  72. commitTransactionAfterReturning(txInfo);
  73. return retVal;
  74. }
  75. //编程式事务处理
  76. else {
  77. Object result;
  78. final ThrowableHolder throwableHolder = new ThrowableHolder();
  79. // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
  80. try {
  81. result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
  82. TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
  83. try {
  84. Object retVal = invocation.proceedWithInvocation();
  85. if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
  86. // Set rollback-only in case of Vavr failure matching our rollback rules...
  87. retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
  88. }
  89. return retVal;
  90. }
  91. catch (Throwable ex) {
  92. if (txAttr.rollbackOn(ex)) {
  93. // A RuntimeException: will lead to a rollback.
  94. if (ex instanceof RuntimeException) {
  95. throw (RuntimeException) ex;
  96. }
  97. else {
  98. throw new ThrowableHolderException(ex);
  99. }
  100. }
  101. else {
  102. // A normal return value: will lead to a commit.
  103. throwableHolder.throwable = ex;
  104. return null;
  105. }
  106. }
  107. finally {
  108. cleanupTransactionInfo(txInfo);
  109. }
  110. });
  111. }
  112. catch (ThrowableHolderException ex) {
  113. throw ex.getCause();
  114. }
  115. catch (TransactionSystemException ex2) {
  116. if (throwableHolder.throwable != null) {
  117. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  118. ex2.initApplicationException(throwableHolder.throwable);
  119. }
  120. throw ex2;
  121. }
  122. catch (Throwable ex2) {
  123. if (throwableHolder.throwable != null) {
  124. logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
  125. }
  126. throw ex2;
  127. }
  128. // Check result state: It might indicate a Throwable to rethrow.
  129. if (throwableHolder.throwable != null) {
  130. throw throwableHolder.throwable;
  131. }
  132. return result;
  133. }
  134. }

(二) 声明式事务处理

1.主要步骤:

(1)创建并获取事务属性

(2)加载配置中配置的TransactionManager

(3)不同的事务处理方式使用不同的逻辑

(4)在目标方法执行前获取食物并收集事务信息

(5)执行目标方法

(6)一旦出现异常,尝试异常处理

(7)提交事务前的事务信息清除

(8)提交事务

2.创建并获取事务属性

  1. protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
  2. @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
  3. // If no name specified, apply method identification as transaction name.
  4. //如果没有名称指定则使用方法唯一标识,并使用DelegatingTransactionAttribute封装txAttr
  5. if (txAttr != null && txAttr.getName() == null) {
  6. txAttr = new DelegatingTransactionAttribute(txAttr) {
  7. @Override
  8. public String getName() {
  9. return joinpointIdentification;
  10. }
  11. };
  12. }
  13. TransactionStatus status = null;
  14. if (txAttr != null) {
  15. //2.获取TransactionStatus
  16. if (tm != null) {
  17. status = tm.getTransaction(txAttr);
  18. }
  19. else {
  20. if (logger.isDebugEnabled()) {
  21. logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
  22. "] because no transaction manager has been configured");
  23. }
  24. }
  25. }
  26. //3.根据指定的属性与status准备一个TransactionInfo
  27. return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  28. }

 (1)使用DelegatingTransactionAttribute封装传入的TransactionAttribute实例

(2)获取事务

(3)构建事务信息

获取事务 getTransaction()

  1. public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
  2. throws TransactionException {
  3. // Use defaults if no transaction definition given.
  4. TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
  5. //获取事务
  6. Object transaction = doGetTransaction();
  7. boolean debugEnabled = logger.isDebugEnabled();
  8. //判断当前线程是否存在事务,判断依据为当前线程记录的连接不为空且连接中connectionHolder中的TransactionActive属性不为空
  9. if (isExistingTransaction(transaction)) {
  10. // Existing transaction found -> check propagation behavior to find out how to behave.
  11. //当前线程已经存在事务
  12. return handleExistingTransaction(def, transaction, debugEnabled);
  13. }
  14. // Check definition settings for new transaction.
  15. //事务超时设置验证
  16. if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
  17. throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
  18. }
  19. // No existing transaction found -> check propagation behavior to find out how to proceed.
  20. //如果当前线程不存在事务,但是PropagationBehavior却被声明为PROPAGATION_MANDATORY则抛出异常
  21. if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
  22. throw new IllegalTransactionStateException(
  23. "No existing transaction found for transaction marked with propagation 'mandatory'");
  24. }
  25. else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
  26. def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
  27. def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  28. //PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED都需要新建事务
  29. //空挂起
  30. SuspendedResourcesHolder suspendedResources = suspend(null);
  31. if (debugEnabled) {
  32. logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
  33. }
  34. try {
  35. return startTransaction(def, transaction, debugEnabled, suspendedResources);
  36. }
  37. catch (RuntimeException | Error ex) {
  38. resume(null, suspendedResources);
  39. throw ex;
  40. }
  41. }
  42. else {
  43. // Create "empty" transaction: no actual transaction, but potentially synchronization.
  44. if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
  45. logger.warn("Custom isolation level specified but no actual transaction initiated; " +
  46. "isolation level will effectively be ignored: " + def);
  47. }
  48. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  49. //新同步事务的设置,针对于当前线程的设置
  50. return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
  51. }
  52. }
  1. private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
  2. boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
  3. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  4. DefaultTransactionStatus status = newTransactionStatus(
  5. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  6. doBegin(transaction, definition);
  7. prepareSynchronization(status, definition);
  8. return status;
  9. }
  1. protected void doBegin(Object transaction, TransactionDefinition definition) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  3. Connection con = null;
  4. //尝试获取连接
  5. try {
  6. if (!txObject.hasConnectionHolder() ||
  7. txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
  8. Connection newCon = obtainDataSource().getConnection();
  9. if (logger.isDebugEnabled()) {
  10. logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
  11. }
  12. txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
  13. }
  14. txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
  15. con = txObject.getConnectionHolder().getConnection();
  16. //设置隔离级别
  17. Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
  18. txObject.setPreviousIsolationLevel(previousIsolationLevel);
  19. txObject.setReadOnly(definition.isReadOnly());
  20. // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
  21. // so we don't want to do it unnecessarily (for example if we've explicitly
  22. // configured the connection pool to set it already).
  23. //更改自动提交设置,由Spring控制提交
  24. if (con.getAutoCommit()) {
  25. txObject.setMustRestoreAutoCommit(true);
  26. if (logger.isDebugEnabled()) {
  27. logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
  28. }
  29. con.setAutoCommit(false);
  30. }
  31. prepareTransactionalConnection(con, definition);
  32. //设置判断当前线程是否存在事务的依据
  33. txObject.getConnectionHolder().setTransactionActive(true);
  34. int timeout = determineTimeout(definition);
  35. if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
  36. //设置过期时间 txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
  37. }
  38. // Bind the connection holder to the thread.
  39. if (txObject.isNewConnectionHolder()) {
  40. //将当前获取到的连接绑定到当前线程 TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
  41. }
  42. }
  43. catch (Throwable ex) {
  44. if (txObject.isNewConnectionHolder()) {
  45. DataSourceUtils.releaseConnection(con, obtainDataSource());
  46. txObject.setConnectionHolder(null, false);
  47. }
  48. throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
  49. }
  50. }

(1)尝试获取连接

(2)设置隔离级别以及只读标识

(3)更改默认的提交设置

(4)设置标志位,标识当前连接已经被事务激活

(5)设置过期时间

(6)将connectionHolder绑定到当前线程

(7)将事务信息记录在当前线程中


2.处理已经存在的事务

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

(1)PROPAGATION_REQUIRES_NEW 标识当前方法必须在它自己的事务里运行,一个新的事务将被启动,而如果有一个事务正在运行的话,则这个方法运行期间被挂起

(2)PROPAGATION_NESTED 表示如果当前正有一个事务在运行中,则该方法应该运行在一个嵌套的事务中,被嵌套的事务可以独立于封装事务进行提交或者回滚


(三)回滚处理

  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. //这里判断是否回滚默认的依据是抛出的异常是否是RuntimeException
  9. if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
  10. try {
  11. //根据TransactionStatus信息进行回滚处理
  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. // We don't roll back on this exception.
  27. // Will still roll back if TransactionStatus.isRollbackOnly() is true.
  28. try {
  29. txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
  30. }
  31. catch (TransactionSystemException ex2) {
  32. logger.error("Application exception overridden by commit exception", ex);
  33. ex2.initApplicationException(ex);
  34. throw ex2;
  35. }
  36. catch (RuntimeException | Error ex2) {
  37. logger.error("Application exception overridden by commit exception", ex);
  38. throw ex2;
  39. }
  40. }
  41. }
  42. }

1.回滚条件 txInfo.transactionAttribute.rollbackOn(ex)txInfo.transactionAttribute.rollbackOn(ex)

2.回滚处理

3.回滚后的信息清楚

  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. //激活所有TransactionSynchronization中对应的方法
  15. triggerBeforeCompletion(status);
  16. if (status.hasSavepoint()) {
  17. if (status.isDebug()) {
  18. logger.debug("Rolling back transaction to savepoint");
  19. }
  20. //如果有保存点,也就是当前事务为单独的线程则会退到保存点
  21. status.rollbackToHeldSavepoint();
  22. }
  23. else if (status.isNewTransaction()) {
  24. if (status.isDebug()) {
  25. logger.debug("Initiating transaction rollback");
  26. }
  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. //激活所有TransactionSynchronization中对应的方法
  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. }
  1. private void cleanupAfterCompletion(DefaultTransactionStatus status) {
  2. //设置完成状态
  3. status.setCompleted();
  4. if (status.isNewSynchronization()) {
  5. TransactionSynchronizationManager.clear();
  6. }
  7. if (status.isNewTransaction()) {
  8. //清除资源
  9. doCleanupAfterCompletion(status.getTransaction());
  10. }
  11. if (status.getSuspendedResources() != null) {
  12. if (status.isDebug()) {
  13. logger.debug("Resuming suspended transaction after completion of inner transaction");
  14. }
  15. Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
  16. //结束之前事务的挂起状态
  17. resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
  18. }
  19. }

  1. protected void doCleanupAfterCompletion(Object transaction) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  3. // Remove the connection holder from the thread, if exposed.
  4. if (txObject.isNewConnectionHolder()) {
  5. //将数据库连接从当前线程中解除绑定
  6. TransactionSynchronizationManager.unbindResource(obtainDataSource());
  7. }
  8. // Reset connection.
  9. //释放连接
  10. Connection con = txObject.getConnectionHolder().getConnection();
  11. try {
  12. if (txObject.isMustRestoreAutoCommit()) {
  13. //恢复数据库连接的自动提交属性
  14. con.setAutoCommit(true);
  15. }
  16. //重置数据库连接
  17. DataSourceUtils.resetConnectionAfterTransaction(
  18. con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());
  19. }
  20. catch (Throwable ex) {
  21. logger.debug("Could not reset JDBC Connection after transaction", ex);
  22. }
  23. if (txObject.isNewConnectionHolder()) {
  24. if (logger.isDebugEnabled()) {
  25. logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
  26. }
  27. //如果当前事务时独立的新创建的事务则在事务完成时释放数据库连接
  28. DataSourceUtils.releaseConnection(con, this.dataSource);
  29. }
  30. txObject.getConnectionHolder().clear();
  31. }

(四) 事务提交

  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. }

当事务没有被异常捕获的时候并不意味着一定会执行提交的过程

  1. public final void commit(TransactionStatus status) throws TransactionException {
  2. if (status.isCompleted()) {
  3. throw new IllegalTransactionStateException(
  4. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  5. }
  6. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  7. //如果在事务链中已经被标记回滚,那么不会尝试提交事务,直接回滚
  8. if (defStatus.isLocalRollbackOnly()) {
  9. if (defStatus.isDebug()) {
  10. logger.debug("Transactional code has requested rollback");
  11. }
  12. processRollback(defStatus, false);
  13. return;
  14. }
  15. if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
  16. if (defStatus.isDebug()) {
  17. logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
  18. }
  19. processRollback(defStatus, true);
  20. return;
  21. }
  22. //处理事务提交
  23. processCommit(defStatus);
  24. }

当事务执行一切都正常的时候,便可以真正的进入提交流程

  1. private void processCommit(DefaultTransactionStatus status) throws TransactionException {
  2. try {
  3. boolean beforeCompletionInvoked = false;
  4. try {
  5. boolean unexpectedRollback = false;
  6. //预留
  7. prepareForCommit(status);
  8. //添加的TransactionSynchronization中的对应方法的调用
  9. triggerBeforeCommit(status);
  10. triggerBeforeCompletion(status);
  11. beforeCompletionInvoked = true;
  12. if (status.hasSavepoint()) {
  13. if (status.isDebug()) {
  14. logger.debug("Releasing transaction savepoint");
  15. }
  16. unexpectedRollback = status.isGlobalRollbackOnly();
  17. //如果存在保存点则清除保存点信息
  18. status.releaseHeldSavepoint();
  19. }
  20. else if (status.isNewTransaction()) {
  21. if (status.isDebug()) {
  22. logger.debug("Initiating transaction commit");
  23. }
  24. unexpectedRollback = status.isGlobalRollbackOnly();
  25. //如果是独立的事务则直接提交
  26. doCommit(status);
  27. }
  28. else if (isFailEarlyOnGlobalRollbackOnly()) {
  29. unexpectedRollback = status.isGlobalRollbackOnly();
  30. }
  31. // Throw UnexpectedRollbackException if we have a global rollback-only
  32. // marker but still didn't get a corresponding exception from commit.
  33. if (unexpectedRollback) {
  34. throw new UnexpectedRollbackException(
  35. "Transaction silently rolled back because it has been marked as rollback-only");
  36. }
  37. }
  38. catch (UnexpectedRollbackException ex) {
  39. // can only be caused by doCommit
  40. triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
  41. throw ex;
  42. }
  43. catch (TransactionException ex) {
  44. // can only be caused by doCommit
  45. if (isRollbackOnCommitFailure()) {
  46. doRollbackOnCommitException(status, ex);
  47. }
  48. else {
  49. triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
  50. }
  51. throw ex;
  52. }
  53. catch (RuntimeException | Error ex) {
  54. if (!beforeCompletionInvoked) {
  55. triggerBeforeCompletion(status);
  56. }
  57. //提交过程中出现异常则回滚
  58. doRollbackOnCommitException(status, ex);
  59. throw ex;
  60. }
  61. // Trigger afterCommit callbacks, with an exception thrown there
  62. // propagated to callers but the transaction still considered as committed.
  63. try {
  64. //添加的TransactionSynchronization中的对应方法的调用
  65. triggerAfterCommit(status);
  66. }
  67. finally {
  68. triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
  69. }
  70. }
  71. finally {
  72. cleanupAfterCompletion(status);
  73. }
  74. }
  1. protected void doCommit(DefaultTransactionStatus status) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
  3. Connection con = txObject.getConnectionHolder().getConnection();
  4. if (status.isDebug()) {
  5. logger.debug("Committing JDBC transaction on Connection [" + con + "]");
  6. }
  7. try {
  8. con.commit();
  9. }
  10. catch (SQLException ex) {
  11. throw new TransactionSystemException("Could not commit JDBC transaction", ex);
  12. }
  13. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/225438
推荐阅读
相关标签
  

闽ICP备14008679号