1、事务传播特性
Springs事务传播特性:名称 | 解释 | |
REQUIRED | 支持当前事务,如果当前没有事务,就新建一个事务。 Spring 默认的事务传播特性 | 支持外层事务 |
SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行 | |
MANDATORY | 支持当前事务,如果当前没有事务,则抛出异常 | |
REQUIRES_NEW | 新建事务,如果当前存在事务,则事务挂起,新增一个事务,新建的事务和当前的事务没有任何关系,是两个独立的事务,外层的事务失败回归后,不能回滚内层事务的运行结果,内层事务失败抛出异常,外层事务有捕获,也能不回滚事务操作 | 不支持外层事务 |
NOT_SUPPORTED | 不执行当前事务;而是总是执行非事务 | |
NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常 | |
NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作 | 嵌套事务 |
2、外层传播特性REQUIRED为例分析Spring事务传播特性
外层的传播特性为REQUIRED,首先外层会新建一个事务TransactionInfo,如果已存在事务,那么内存的事务该如何执行?我们接着往下分析。
2.1、已存在事务执行流程入口
AbstractPlatformTransactionManager#getTransaction 获取事务状态核心伪代码:1 // 获取事务信息 2 public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { 3 4 // 若不指定事务定义,则使用默认的事务定义StaticTransactionDefinition 5 TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults()); 6 7 // 获取数据源对象 DataSourceTransactionObject 8 Object transaction = doGetTransaction(); 9 boolean debugEnabled = logger.isDebugEnabled(); 10 11 // 若已存在事务,按已存在事务流程执行 12 if (isExistingTransaction(transaction)) { 13 return handleExistingTransaction(def, transaction, debugEnabled); 14 } 15 }
1、创建数据源对象
AbstractPlatformTransactionManager#doGetTransaction 获取数据源属性对象核心代码:1 // 创建数据源属性对象,并填充属性 2 protected Object doGetTransaction() { 3 // 创建一个数据源事务对象 4 DataSourceTransactionObject txObject = new DataSourceTransactionObject(); 5 // 是否允许当前事务设置保存点 6 txObject.setSavepointAllowed(isNestedTransactionAllowed()); 7 // 对于内层被增强方法而言,数据源对应的jdbc连接在创建新事务时, 在事务同步管理器中已经完成初始化,此处事务管理器的jdbc连接不为空 8 ConnectionHolder conHolder = 9 (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource()); 10 txObject.setConnectionHolder(conHolder, false); 11 // 返回事务对象 12 return txObject; 13 }
创建数据源属性对象,并设置是否允许当前事务设置保存点,并获取数据源对应的jdbc连接,设置进数据源属性对象中。
2、是否为已存在的事务
DataSourceTransactionManager#isExistingTransaction 是否已存在事务核心代码1 protected boolean isExistingTransaction(Object transaction) { 2 DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; 3 // 判断数据源事务对象中是否有连接持有器,并且事务处理激活状态 4 return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive()); 5 }
3、执行已存在事务流程概览
3.1、核心流程图
3.2、核心伪代码
AbstractPlatformTransactionManager#handleExistingTransaction 执行已存在事务核心伪代码:1 private TransactionStatus handleExistingTransaction( 2 TransactionDefinition definition, Object transaction, boolean debugEnabled) 3 throws TransactionException { 4 5 // 当前事务行为为PROPAGATION_NEVER, 不支持事务,但是当前又存在一个事务,所以抛出异常 6 if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) { 7 throw new IllegalTransactionStateException( 8 "Existing transaction found for transaction marked with propagation 'never'"); 9 } 10 11 // 当前事务行为为PROPAGATION_NOT_SUPPORTED, 挂起已经存在的事务, 以非事务状态运行 12 if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) { 13 // 挂起当前事务并返回挂起的资源持有器 14 Object suspendedResources = suspend(transaction); 15 boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); 16 // 创建一个新的非事务状态(保存了上一个存在事务状态的属性) 17 return prepareTransactionStatus( 18 definition, null, false, newSynchronization, debugEnabled, suspendedResources); 19 } 20 21 // 当前事务行为为PROPAGATION_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 // 创建事务(保存了上一个存在事务状态的属性) 31 return startTransaction(definition, transaction, debugEnabled, suspendedResources); 32 } 33 catch (RuntimeException | Error beginEx) { 34 resumeAfterBeginException(transaction, suspendedResources, beginEx); 35 throw beginEx; 36 } 37 } 38 39 // 当前事务行为PROPAGATION_NESTED,判断是否允许嵌套事务,不允许,抛异常; 40 // 否则,判断是否使用保存点执行Nest事务,若使用保存点,创建事务状态对象,并为当前事务创建一个保存点,返回事务状态对象; 41 // 若不使用保存点执行Nest事务,创建事务执行 42 if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { 43 // 支持嵌套事务,不允许就报异常 44 if (!isNestedTransactionAllowed()) { 45 throw new NestedTransactionNotSupportedException( 46 "Transaction manager does not allow nested transactions by default - " + 47 "specify 'nestedTransactionAllowed' property with value 'true'"); 48 } 49 50 // 是否使用保存点执行nest事务,默认为true 51 if (useSavepointForNestedTransaction()) { 52 // 如果没有可以使用保存点的方式控制事务回滚,那么在嵌入式事务的建立初始保存点 53 DefaultTransactionStatus status = 54 prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null); 55 // 为事务设置一个回退点 56 status.createAndHoldSavepoint(); 57 return status; 58 } 59 else { 60 // 不使用保存点的操作 61 return startTransaction(definition, transaction, debugEnabled, null); 62 } 63 } 64 65 // 若为REQUIRED 66 // 事务是否需要同步标识 67 boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); 68 // 创建事务状态对象,newTransaction标识设置为false,标识不是一个新事务 69 return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null); 70 }