前置学习:springboot事务_springboot启动事务-CSDN博客
PlatformTransactionManager#getTransaction
PROPAGATION_REQUIRED
如果存在事务,就开启当前事务,如果不存在事务,则创建事务
1、存在事务的场景,就返回当前的TransactionStatus
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
2、不存在事务的场景则创建一个新事务:
org.springframework.transaction.support.AbstractPlatformTransactionManager#startTransaction
PROPAGATION_REQUIRES_NEW
总是先挂起当前事务,并且创建并且开启一个新事务。
1、存在当前事务的时候,先挂起当前事务,会存档一个SuspendedResourcesHolder,用来存储被挂起的事务信息。然后开启一个新事务startTransaction。
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
org.springframework.transaction.support.AbstractPlatformTransactionManager#suspend
protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
try {
Object suspendedResources = null;
if (transaction != null) {
suspendedResources = doSuspend(transaction);
}
String name = TransactionSynchronizationManager.getCurrentTransactionName();
TransactionSynchronizationManager.setCurrentTransactionName(null);
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.setActualTransactionActive(false);
return new SuspendedResourcesHolder(
suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
}
catch (RuntimeException ex) {
// doSuspend failed - original transaction is still active...
doResumeSynchronization(suspendedSynchronizations);
throw ex;
}
catch (Error err) {
// doSuspend failed - original transaction is still active...
doResumeSynchronization(suspendedSynchronizations);
throw err;
}
}
else if (transaction != null) {
// Transaction active but no synchronization active.
Object suspendedResources = doSuspend(transaction);
return new SuspendedResourcesHolder(suspendedResources);
}
else {
// Neither transaction nor synchronization active.
return null;
}
}
2、不存在当前事务的情况
当前不存在事务的时候,从ThreadLocal中取出当前事务,并且进行存档一个SuspendedResourcesHolder,同时设置当前事务的名称、隔离级别、只读全部为空。SuspendedResourcesHolder会作为旧的事务存档到当前事务中。
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
ROPAGATION_NESTED
如果已经存在事务,那么运行在在这个嵌套事务中。如果不存在事务,则创建一个新的事务。
Mysql使用safepoint完成事务的部分回滚,语法如下;
1.定义保存点---SAVEPOINT 保存点名;
2.回滚到指定保存点---ROLLBACK TO SAVEPOINT 保存点名:
1、如果已经存在当前事务,则运行在当前事务中,
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction。
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
prepareTransactionStatus第三个参数代表newTransaction为false,代表在startTransaction是不会再创建一个新的事务的。
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
}
2、如果不存在当前事务,则挂起当前事务(所有事务信息全挂为null,并且不持有任何connect连接),并且创建一个新的事务,保留旧事务的suspendedResources。
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
PROPAGATION_SUPPORTS
如果已经存在事务,那么使用当前事务。如果没有事务,则非事务的执行。
这个传播机制在源码上来说,是根本不做任何处理的,基本上走的默认预备事务处理(prepareTransactionStatus)
1、存在事务的场景,沿用旧事务
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
2、不存在事务的场景,则返回一个默认的事务,但是第二个值为null,实际就是以非事务运行。
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
PROPAGATION_NOT_SUPPORTED
总是非事务地执行,并挂起任何存在的事务。
1、已存在当前事务的场景:不会创建新的事务,并且挂起当前事务,记录一个存档
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
2、不存在事务的场景,则返回一个默认的事务,但是第二个值为null,实际就是以非事务运行。
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
PROPAGATION_MANDATORY
必须在一个事务中运行,如果没有事务,将抛出异常。(这一块有争议)
这个实现就非常简单了。
只是判断在当前事务,没有事务的情况,立马返回一个异常。
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
PROPAGATION_NEVER
总是非事务地执行,如果在事务中运行,则抛出异常。
org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}