当前位置:   article > 正文

Spring事务源码:事务创建_如何确保datasourceutils.getconnection()获取当前事务

如何确保datasourceutils.getconnection()获取当前事务

参考文章:

《Spring 源码解析—事务执行》

《Spring事务源码解析之事务回滚篇》

《Spring事务源码解析之事务提交篇》

前文:

《Spring事务源码:创建代理类》

        写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。

前言

        在前文中我们介绍了Spring事务管理是如何开启以及创建代理类对象的,本文我们来深入解析下代理类是如何实现事务的管控。

目录

前言

一、代理类中方法执行

二、事务管理

        1、invokeWithinTransaction

        2、createTransactionIfNecessary

三、开启事务

        1、获取当前事务

        2、获取事务对象

        2.1、dataSource

        2.2、getResource

        3、判断是否存在事务

        4、挂起事务

        4.1、suspend

        4.2、doSuspend

        5、开启新事务

        6、绑定线程与数据库连接

        7、创建默认status

        8、存在原事务时的处理方案


一、代理类中方法执行

        在以前讲AOP的时候我们介绍过在执行代理类的目标方法时,会调用Advisor的getAdvice方法获取MethodInterceptor接口实现类并执行其invoke方法。前一篇文章中我们看到了BeanFactoryTransactionAttributeSourceAdvisor的adviceBeanName便是TransactionInterceptor,该类继承了MethodInterceptor接口。

  1. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
  2. String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
  3. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
  4. advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
  5. parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

        我们从TransactionInterceptor类的invoke方法开始分析,首先获取被代理类,然后调用invokeWithinTransaction方法,该方法内部将会把被代理类的方法纳入事务中。

  1. @Override
  2. public Object invoke(final MethodInvocation invocation) throws Throwable {
  3. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
  4. // 在事务中执行被代理类的方法
  5. return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
  6. @Override
  7. public Object proceedWithInvocation() throws Throwable {
  8. return invocation.proceed();
  9. }
  10. });
  11. }

        

二、事务管理

        1、invokeWithinTransaction

        invokeWithinTransaction方法首先获取了事务属性和事务管理器,然后针对声明式事务与编程式事务进行了区分处理,我们这里只对声明式事务进行分析。

        不同的事务处理方式使用不同的逻辑。对于声明式事务的处理与编程式事务的处理,第一点区别在于事务属性上,因为声明式事务处理是可以没有事务属性的,第二点区别就是在TransactionManager上,CallbackPreferringPlatformTransactionManager实现PlatformTransactionManager接口,暴露出一个方法用于执行事务处理中的回调。所以,这两种方式都可以用作事务处理方式的判断。

  1. protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
  2. throws Throwable {
  3. // 获取事务属性
  4. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
  5. // 获取beanFactory中的transactionManager
  6. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
  7. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  8. // 声明式事务处理
  9. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  10. ...
  11. }
  12. else {
  13. // 编程式事务处理
  14. try {
  15. ...
  16. }
  17. catch (ThrowableHolderException ex) {
  18. throw ex.getCause();
  19. }
  20. }
  21. }

        声明式事务的处理过程中,首先会创建事务,即开启事务(这里会返回一个TransactionInfo用来保存事务的数据,便于后续流程中回滚与提交),然后调用被代理类中的方法,方法执行完后根据执行结果判断是回滚还是提交事务。注意无论是回滚还是提交最后都需要将事务信息清空。

  1. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
  2. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
  3. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  4. // 声明式事务处理
  5. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  6. // 创建事务,事务属性等信息会被保存进TransactionInfo中
  7. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
  8. Object retVal;
  9. try {
  10. // 执行目标方法
  11. retVal = invocation.proceedWithInvocation();
  12. }
  13. catch (Throwable ex) {
  14. // 异常处理
  15. completeTransactionAfterThrowing(txInfo, ex);
  16. throw ex;
  17. }
  18. finally {
  19. // 清空事务信息
  20. cleanupTransactionInfo(txInfo);
  21. }
  22. // 提交事务
  23. commitTransactionAfterReturning(txInfo);
  24. return retVal;
  25. }

        2、createTransactionIfNecessary

        首先调用getTransaction方法,该方法内部将会判断是否需要开启事务并绑定线程与数据库连接,是非常重要的过程,我们下面会做详细介绍。

        然后调用prepareTransactionInfo方法根据事务属性与status准备一个TransactionInfo。这是因为当已经建立事务连接并完成了事务信息的提取后,我们需要将所有的事务信息统一记录在TransactionInfo类型的实例中,这个实例包含了目标方法开始前的所有状态信息,一旦事务执行失败,Spring会通过TransactionInfo类型的实例中的信息来进行回滚等后续工作。

  1. protected TransactionInfo createTransactionIfNecessary(
  2. PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
  3. // 如果事务属性没有名称指定则使用方法唯一标识,并使用DelegatingTransactionAttribute封装txAttr
  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. // 获取事务状态TransactionStatus
  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. // 构建事务信息,根据指定的属性与status构建一个TransactionInfo
  26. return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  27. }

三、开启事务

        1、获取当前事务

        首先根据doGetTransaction获取当前事务,然后调用isExistingTransaction判断是否存在事务,如果已经存在则进入handleExistingTransaction方法进行处理。

        如果不存在事务属性为REQUIRED、REQUIRES_NEW、NESTED则表明需要开启新事务,将会先将空事务挂起(之所以没有原事务也挂起是为了后续回滚或提交时做判断),然后doBegin开启事务,并调用prepareSynchronization将新事务的信息保存到当前线程中。

        如果都不是(例如SUPPORTS)则创建一个DefaultTransactionStatus。

  1. public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
  2. // 获取事务
  3. Object transaction = doGetTransaction();
  4. boolean debugEnabled = logger.isDebugEnabled();
  5. if (definition == null) {
  6. definition = new DefaultTransactionDefinition();
  7. }
  8. // 判断当前线程是否已经存在事务
  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. // 如果当前线程不存在事务并且事务传播行为为 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. // 这三种事务传播行为需要开启新事务
  23. else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
  24. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
  25. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  26. // 挂起原事务,因为这里不存在原事务因此是null
  27. SuspendedResourcesHolder suspendedResources = suspend(null);
  28. if (debugEnabled) {
  29. logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
  30. }
  31. try {
  32. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  33. DefaultTransactionStatus status = newTransactionStatus(
  34. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  35. // 开启事务
  36. doBegin(transaction, definition);
  37. // 同步事务状态
  38. prepareSynchronization(status, definition);
  39. return status;
  40. }
  41. catch (RuntimeException ex) {
  42. resume(null, suspendedResources);
  43. throw ex;
  44. }
  45. catch (Error err) {
  46. resume(null, suspendedResources);
  47. throw err;
  48. }
  49. }
  50. else {
  51. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
  52. logger.warn("Custom isolation level specified but no actual transaction initiated; " +
  53. "isolation level will effectively be ignored: " + definition);
  54. }
  55. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  56. return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
  57. }
  58. }

        2、获取事务对象

        doGetTransaction方法可以获取事务对象

  1. protected Object doGetTransaction() {
  2. DataSourceTransactionObject txObject = new DataSourceTransactionObject();
  3. txObject.setSavepointAllowed(isNestedTransactionAllowed());
  4. // this.dataSource即数据源,判断当前线程如果已经记录数据库连接则使用原有连接
  5. ConnectionHolder conHolder =
  6. (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
  7. // false表示非新创建连接
  8. txObject.setConnectionHolder(conHolder, false);
  9. return txObject;
  10. }

        2.1、dataSource

        这里的this.dataSource是我们在设置DataSourceTransactionManager时传入的(回顾下前文的事务配置)

  1. <tx:annotation-driven transaction-manager="transactionManager"/>
  2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource"/>
  4. </bean>
  1. public DataSourceTransactionManager(DataSource dataSource) {
  2. this();
  3. // 设置数据源
  4. setDataSource(dataSource);
  5. afterPropertiesSet();
  6. }

        2.2、getResource

        TransactionSynchronizationManager持有一个ThreadLocal的实例,其中存放了一个Map,该Map的key为datasource,value为ConnectionHolder。

  1. // 用 ThreadLocal 来存放 ConnectionHolder 信息
  2. private static final ThreadLocal<Map<Object, Object>> resources =
  3. new NamedThreadLocal<>("Transactional resources");
  4. // 获取ConnectionHolder
  5. public static Object getResource(Object key) {
  6. // 包装下传入的 key
  7. Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
  8. // 在这里获取连接信息
  9. Object value = doGetResource(actualKey);
  10. return value;
  11. }
  12. // 具体的获取操作
  13. private static Object doGetResource(Object actualKey) {
  14. // 从ThreadLocal中获取
  15. Map<Object, Object> map = resources.get();
  16. if (map == null) {
  17. return null;
  18. }
  19. Object value = map.get(actualKey);
  20. if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
  21. map.remove(actualKey);
  22. if (map.isEmpty()) {
  23. resources.remove();
  24. }
  25. value = null;
  26. }
  27. return value;
  28. }

        这个ConnectionHolder可以简单地将其理解为Connection(数据库连接)的包装类,其中最重要的属性就是Connection了。

  1. public class ConnectionHolder extends ResourceHolderSupport {
  2. // 当前数据库连接
  3. private final Connection connection;
  4. public ConnectionHolder(Connection connection) {this.connection = connection;}
  5. public Connection getConnection() {return this.connection;}
  6. }

        3、判断是否存在事务

        判断当前线程是否存在事务,判读依据为当前线程记录的连接不为空且连接中(connectionHolder)中的transactionActive属性不为空。

  1. @Override
  2. protected boolean isExistingTransaction(Object transaction) {
  3. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  4. return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
  5. }

        4、挂起事务

        4.1、suspend

        suspend方法对有无同步的事务采取了不同的方案,但真正挂起事务都是使用的doSuspend

  1. protected final SuspendedResourcesHolder suspend(@Nullable Object transaction)
  2. throws TransactionException {
  3. // 如果有同步的事务,则优先挂起同步的事务
  4. if (TransactionSynchronizationManager.isSynchronizationActive()) {
  5. List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
  6. try {
  7. Object suspendedResources = null;
  8. if (transaction != null) {
  9. // 挂起操作
  10. suspendedResources = doSuspend(transaction);
  11. }
  12. // 重置事务名称
  13. String name = TransactionSynchronizationManager.getCurrentTransactionName();
  14. TransactionSynchronizationManager.setCurrentTransactionName(null);
  15. // 重置只读状态
  16. boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
  17. TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
  18. // 重置隔离级别
  19. Integer isolationLevel = TransactionSynchronizationManager
  20. .getCurrentTransactionIsolationLevel();
  21. TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
  22. // 重置事务激活状态
  23. boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
  24. TransactionSynchronizationManager.setActualTransactionActive(false);
  25. // 返回挂起的事务
  26. return new SuspendedResourcesHolder(
  27. suspendedResources, suspendedSynchronizations, name, readOnly,
  28. isolationLevel, wasActive);
  29. }
  30. catch (RuntimeException | Error ex) {
  31. doResumeSynchronization(suspendedSynchronizations);
  32. throw ex;
  33. }
  34. }
  35. else if (transaction != null) {
  36. Object suspendedResources = doSuspend(transaction);
  37. return new SuspendedResourcesHolder(suspendedResources);
  38. }
  39. else {
  40. return null;
  41. }
  42. }

        4.2、doSuspend

        可以看出挂起操作主要是将当前connectionHolder置为null,返回原有事务信息,以便于后续恢复原有事务,并将当前正在进行的事务信息进行重置。

  1. protected Object doSuspend(Object transaction) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  3. txObject.setConnectionHolder(null);
  4. // 解除绑定
  5. return TransactionSynchronizationManager.unbindResource(this.dataSource);
  6. }

         继续进入TransactionSynchronizationManager.unbindResource来看解绑的操作,其实就是将现有的事务信息remove并返回上一级以便保存。

  1. // 解除绑定操作
  2. public static Object unbindResource(Object key) throws IllegalStateException {
  3. Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
  4. // 继续调用
  5. Object value = doUnbindResource(actualKey);
  6. if (value == null) {
  7. throw new IllegalStateException(...);
  8. }
  9. return value;
  10. }
  11. // 解除绑定操作
  12. private static Object doUnbindResource(Object actualKey) {
  13. Map<Object, Object> map = resources.get();
  14. if (map == null) {
  15. return null;
  16. }
  17. // 移除资源
  18. Object value = map.remove(actualKey);
  19. if (map.isEmpty()) {
  20. resources.remove();
  21. }
  22. if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
  23. value = null;
  24. }
  25. return value;
  26. }

        5、开启新事务

        这里我们看到了数据库连接的获取,如果是新事务需要获取新一个新的数据库连接,并为其设置了隔离级别、是否只读等属性。

  1. protected void doBegin(Object transaction, TransactionDefinition definition) {
  2. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  3. Connection con = null;
  4. try {
  5. // 新事务开启时将ConnectionHolder置为了null
  6. if (txObject.getConnectionHolder() == null ||
  7. txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
  8. Connection newCon = this.dataSource.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. // 设置事务隔离级别和readOnly属性
  17. Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
  18. txObject.setPreviousIsolationLevel(previousIsolationLevel);
  19. if (con.getAutoCommit()) {
  20. txObject.setMustRestoreAutoCommit(true);
  21. if (logger.isDebugEnabled()) {
  22. logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
  23. }
  24. // 设置由Spring控制事务提交
  25. con.setAutoCommit(false);
  26. }
  27. prepareTransactionalConnection(con, definition);
  28. // 设置当前线程的事务激活状态
  29. txObject.getConnectionHolder().setTransactionActive(true);
  30. int timeout = determineTimeout(definition);
  31. if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
  32. // 设置超时时间
  33. txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
  34. }
  35. if (txObject.isNewConnectionHolder()) {
  36. TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
  37. }
  38. }
  39. catch (Throwable ex) {
  40. if (txObject.isNewConnectionHolder()) {
  41. DataSourceUtils.releaseConnection(con, this.dataSource);
  42. txObject.setConnectionHolder(null, false);
  43. }
  44. throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
  45. }
  46. }

        6、绑定线程与数据库连接

        将事务信息记录到当前线程中

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

        7、创建默认status

        如果不需要开启事务(例如SUPPORTS)则返回一个默认的status对象。

  1. protected final DefaultTransactionStatus prepareTransactionStatus(
  2. TransactionDefinition definition, Object transaction, boolean newTransaction,
  3. boolean newSynchronization, boolean debug, Object suspendedResources) {
  4. DefaultTransactionStatus status = newTransactionStatus(
  5. definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
  6. prepareSynchronization(status, definition);
  7. return status;
  8. }
  9. protected DefaultTransactionStatus newTransactionStatus(
  10. TransactionDefinition definition, Object transaction, boolean newTransaction,
  11. boolean newSynchronization, boolean debug, Object suspendedResources) {
  12. boolean actualNewSynchronization = newSynchronization &&
  13. !TransactionSynchronizationManager.isSynchronizationActive();
  14. // 创建DefaultTransactionStatus对象
  15. return new DefaultTransactionStatus(
  16. transaction, newTransaction, actualNewSynchronization,
  17. definition.isReadOnly(), debug, suspendedResources);
  18. }

        8、存在原事务时的处理方案

        handleExistingTransaction方法针对不同的传播行为做不同的处理方法,比如挂起原事务开启新事务等。

  1. private TransactionStatus handleExistingTransaction(
  2. TransactionDefinition definition, Object transaction, boolean debugEnabled)
  3. throws TransactionException {
  4. // 当传播方式为NEVER时抛出异常
  5. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
  6. throw new IllegalTransactionStateException(
  7. "Existing transaction found for transaction marked with propagation 'never'");
  8. }
  9. // 当传播方式为NOT_SUPPORTED时挂起当前事务,然后在无事务的状态中运行
  10. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
  11. if (debugEnabled) {
  12. logger.debug("Suspending current transaction");
  13. }
  14. // 挂起事务
  15. Object suspendedResources = suspend(transaction);
  16. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  17. // 返回默认status
  18. return prepareTransactionStatus(
  19. definition, null, false, newSynchronization, debugEnabled, suspendedResources);
  20. }
  21. // 当传播方式为REQUIRES_NEW时挂起当前事务,然后启动新的事务
  22. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
  23. if (debugEnabled) {
  24. logger.debug("Suspending current transaction, creating new transaction with name [" +
  25. definition.getName() + "]");
  26. }
  27. // 挂起原事务
  28. SuspendedResourcesHolder suspendedResources = suspend(transaction);
  29. try {
  30. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  31. DefaultTransactionStatus status = newTransactionStatus(
  32. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  33. // 启动新的事务
  34. doBegin(transaction, definition);
  35. prepareSynchronization(status, definition);
  36. return status;
  37. }
  38. catch (RuntimeException beginEx) {
  39. resumeAfterBeginException(transaction, suspendedResources, beginEx);
  40. throw beginEx;
  41. }
  42. catch (Error beginErr) {
  43. resumeAfterBeginException(transaction, suspendedResources, beginErr);
  44. throw beginErr;
  45. }
  46. }
  47. // 当传播方式为NESTED时, 设置事务的保存点
  48. // 存在事务,将该事务标注保存点,形成嵌套事务。
  49. // 嵌套事务中的子事务出现异常不会影响到父事务保存点之前的操作。
  50. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  51. if (!isNestedTransactionAllowed()) {
  52. throw new NestedTransactionNotSupportedException(
  53. "Transaction manager does not allow nested transactions by default - " +
  54. "specify 'nestedTransactionAllowed' property with value 'true'");
  55. }
  56. if (debugEnabled) {
  57. logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
  58. }
  59. if (useSavepointForNestedTransaction()) {
  60. DefaultTransactionStatus status =
  61. prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
  62. // 创建保存点,回滚时只回滚到该保存点
  63. status.createAndHoldSavepoint();
  64. return status;
  65. }
  66. else {
  67. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  68. DefaultTransactionStatus status = newTransactionStatus(
  69. definition, transaction, true, newSynchronization, debugEnabled, null);
  70. // 如果不支持保存点,就启动新的事务
  71. doBegin(transaction, definition);
  72. prepareSynchronization(status, definition);
  73. return status;
  74. }
  75. }
  76. // 其余代码
  77. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  78. return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
  79. }

        到这里我们就分析完了事务的创建工作,下一步就是被代理类方法的执行,执行完之后会根据结果判断是回滚还是提交,这部分我们会在下文进行讲解。

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

闽ICP备14008679号