1.2 事务管理器TransactionManager
org.springframework.transaction.TransactionManager
没有任何方法,仅作为类型标识,通常使用接口org.springframework.transaction.PlatformTransactionManager
,该接口提供三个方法处理事务。事务管理器的类图如下:
其中AbstractPlatformTransactionManager
类是PlatformTransactionManager
接口的基础实现,里面有事务管理器的公共逻辑。在不同场景使用的事务管理器在它的基础上完善细节。
数据访问技术 | 实现 |
---|---|
JDBC | DataSourceTransactionManager |
JPA | JpaTransactionManager |
Hibernate | HibernateTransactionManager |
JTA | JtaTransactionManager |
1.2.1 TransactionStatus
org.springframework.transaction.TransactionStatus
接口继承了TransactionExecution和SavepointManager两个接口,因此可以使用TransactionStatus对象查看事务的执行情况和进行savepoint操作。在DefaultTransactionStatus实现类中,savepoint操作是委托给transaction对象实现的,该对象必须也必须实现SavepointManager
接口
1.3 AbstractPlatformTransactionManager
该类抽象了TransactionManager的工作逻辑,也是上面提到的所有TransactionManager的父类
1.3.1 getTransaction
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// Use defaults if no transaction definition given.
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
Object transaction = doGetTransaction(); // 调用子类的实现获取事务对象
boolean debugEnabled = logger.isDebugEnabled();
// 判断当前是否已经存在事务。该方法默认返回false,但是子类都会有自己的实现
// 判断是否是否已经存在,主要用于处理事务的propagation逻辑
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(def, transaction, debugEnabled);
}
// PROPAGATION_MANDATORY表示需要有事务,没有事务将报错
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 暂停前一个事务,通常为null,返回SuspendedResourcesHolder对象,用于恢复前一个事务
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
// 如果异常了,恢复前一个事务
resume(null, suspendedResources);
throw ex;
}
}
else { // 用户自定义的传播级别
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
开始一个事务
/**
* Start a new transaction.
*/
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
// 默认为true
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
// 获取status对象
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 调用子类的方法,表示要开始一个事务
doBegin(transaction, definition);
// 准备事务同步
prepareSynchronization(status, definition);
return status;
}
/**
* Create a TransactionStatus instance for the given arguments.
*/
protected DefaultTransactionStatus newTransactionStatus(
TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
boolean actualNewSynchronization = newSynchronization &&
!TransactionSynchronizationManager.isSynchronizationActive();
return new DefaultTransactionStatus(
transaction, newTransaction, actualNewSynchronization,
definition.isReadOnly(), debug, suspendedResources);
}
当用户自定传播级别时,获取Status
/**
* Create a new TransactionStatus for the given arguments,
* also initializing transaction synchronization as appropriate.
* @see #newTransactionStatus
* @see #prepareTransactionStatus
*/
protected final DefaultTransactionStatus prepareTransactionStatus(
TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
prepareSynchronization(status, definition);
return status;
}
当已经存在事务
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// PROPAGATION_NEVER表示不能出现在事务中
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
// PROPAGATION_NOT_SUPPORTED表示不支持事务,将会暂停当前事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
// PROPAGATION_REQUIRES_NEW表示需要新的事务,也会暂停当前事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
SuspendedResourcesHolder suspendedResources = suspend(transaction); // 停止当前事务
try {
// startTransaction方法内部会重新获取一个ConnectionHolder
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
// PROPAGATION_NESTED表示采用多层事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) { // isNestedTransactionAllowed返回默认为true
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (useSavepointForNestedTransaction()) { // 通常返回true,jta事务管理器返回false
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint(); // 在status中创建一个savepoint
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.
// JTA是直接通过多层begin和commit/rollback实现多层事务
return startTransaction(definition, transaction, debugEnabled, null);
}
}
// 当PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED时,将参加到当前事务中
if (isValidateExistingTransaction()) { // 默认false
// 检查隔离界别是否相同,不相同表示不能加入当前事务
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
// 检查readonly,不相同表示不能加入当前事务
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
1.3.2 commit
@Override
public final void commit(TransactionStatus status) throws TransactionException {
// 已经commit或rollback的status不能再次commit
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// 本地要回滚,一般为false
if (defStatus.isLocalRollbackOnly()) {
processRollback(defStatus, false);
return;
}
// jta和jpa的实现中shouldCommitOnGlobalRollbackOnly返回true,其他的为false
// 如果当前事务是加入到以前的事务中,如果当前事务失败,将会把status标记为rollbackOnly,也就是整个事务都将回滚
// 一般不会进入到这里
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
processRollback(defStatus, true);
return;
}
processCommit(defStatus);
}
提交事务
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
boolean unexpectedRollback = false;
prepareForCommit(status); // 钩子函数,当前没有子类实现
triggerBeforeCommit(status); // 调用TransactionSynchronization的BeforeCommit方法
triggerBeforeCompletion(status); // 调用TransactionSynchronization的BeforeCompletion方法
beforeCompletionInvoked = true;
if (status.hasSavepoint()) { // 如果当前事务是savepoint实现的
unexpectedRollback = status.isGlobalRollbackOnly();
// 释放当前savepoint
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) { // 如果当前是最外层事务
unexpectedRollback = status.isGlobalRollbackOnly();
// 提交事务
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) { // 如果是中途加入已有的事务,默认为false
unexpectedRollback = status.isGlobalRollbackOnly();
}
// Throw UnexpectedRollbackException if we have a global rollback-only
// marker but still didn't get a corresponding exception from commit.
if (unexpectedRollback) { // 一般不会进入,因为在commit方法中经被拦截了
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
// 调用TransactionSynchronization的AfterCompletion方法
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) { // 一般返回false
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, ex);
throw ex;
}
// Trigger afterCommit callbacks, with an exception thrown there
// propagated to callers but the transaction still considered as committed.
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
// 清理事务
cleanupAfterCompletion(status);
}
}
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
status.setCompleted(); // 设置status的状态
if (status.isNewSynchronization()) { // 清除同步
TransactionSynchronizationManager.clear();
}
if (status.isNewTransaction()) {
doCleanupAfterCompletion(status.getTransaction()); // 默认是空,子类一般都有实现
}
if (status.getSuspendedResources() != null) { //
Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
// 恢复事务
resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
}
}
1.3.3 rollback
@Override
public final void rollback(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus, false); // 回滚
}
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
triggerBeforeCompletion(status);// 调用TransactionSynchronization的BeforeCompletion方法
if (status.hasSavepoint()) { // 当前事务是使用savepoint实现的
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) { // 如果是最外层事务
doRollback(status); // 调用子类得方法
}
else { // 如果是参与到另一个事务
// Participating in larger transaction
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {// isGlobalRollbackOnParticipationFailure一般为true
doSetRollbackOnly(status); // 设置当前status为global的rollbackonly
}
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// Raise UnexpectedRollbackException if we had a global rollback-only marker
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
cleanupAfterCompletion(status);
}
}