通过上一篇《从@Transactional注解看Spring事务》,已经大概了解了事务中的基本使用。这一篇,小编跟大家一起通过Spring中几个重要源码类来增加对Spring事务的了解;
在Spring中实现事务需要很多类的配合,但这里小编主要分析这几个类:TransactionDefinition、PlatformTransactionManager、TransactionStatus、TransactionInceptor;
▶ TransactionDefinition
从字面上来看,这个类主要是做事务的定义。实际上也确实是这样,它是对事务定义的最顶级接口,主要是定义事务隔离级别、事务传播性和事务的只读性等。
TransactionDefinition部分代码:
public interface TransactionDefinition {
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int TIMEOUT_DEFAULT = -1;
// 获取事务的隔离级别
int getPropagationBehavior();
//获取隔离级别
int getIsolationLevel();
//是否超时
int getTimeout();
//校验当前事务是只读
boolean isReadOnly();
@Nullable
String getName();
}
结合类(接口)与类(接口)之间的关系,小编整理出来一张图,用来明确TransactionDefinition这个接口不可撼动的地位:
从上图中,我们可以看到在实现TranscationDefinition这个接口的有DefaultTransactionDefinition类,在这个类中,对TransactionDefinition中的方法进行简单实现;
▶ PlatformTransactionManager
和TransactionDefinition一样,都是接口,并且都是在自己的领域内的顶级接口;PlatformTransactionManager是事务管理器的顶级接口,各持久化框架要想接入spring的事务管理,都必须自行提供该接口的实现。

在这个接口的众多实现类中,有一个不容忽视的类AbstractPlatformTransactionManager;
为什么说它不容忽视呢?在这个类中实现了spring标准的事务流:

综合上图我们很容易得知,在该类中,定义并实现了很多与事务直接相关的方法,在该类中,除了对PlatformTransactionManager中commit(TransactionStatus status),rollback(TransactionStatus status),getTransaction(@Nullable TransactionDefinition definition)三个方法进行重载之外,定义了许多 **TransactionSynchronization、**ValidateExistingTranscation*、**rollbackOnCommitFailure、handleExistingTransaction等的私有或受保护的方法;这些方法覆盖了事务状态、对存在的事务的有效性和处理、提交失败的事务处理等方面,正因为如此,才会在上文中提到“在这个类中实现了spring标准的事务流”;
☞ getTransaction(TransactionDefinition definition):只要是对事务传播行为的处理
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction();
// Cache debug flag to avoid repeated checks.
boolean debugEnabled = logger.isDebugEnabled();
//如果传入的事务定义为空,则初始化一个DefaultTransactionDefinition类
if (definition == null) {
// Use defaults if no transaction definition given.
definition = new DefaultTransactionDefinition();
}
//如果已经存在事务,调用方法处理当前存在的事务
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// No existing transaction found -> check propagation behavior to find out how to proceed.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
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 | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
在方法实现的最后,prepareTransactionStatus方法需要引起我们的注意,最终该方法会调用到一个同名方法:
/**
* status.isNewSynchronization是判断一个新的事务锁定是否已经开启;
*/
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
definition.getIsolationLevel() : null);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
TransactionSynchronizationManager.initSynchronization();
}
}
因此,getTransaction方法其实就是对我们平时对事务设置的传播行为进行的分析和处理。{提前透漏,该方法是事务实现的直接被调用方,稍后会讲到}
☞ commit(TransactionStatus status):
@Override
public final void commit(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;
//如果属性为只是当前事务回滚,则执行当前事务的回滚
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus, false);
return;
}
//如果事务的回滚属性为全局回滚
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus, true);
return;
}
//将事务的当前状态,提交事务
processCommit(defStatus);
}
当我们使用编程式事务时手动提交事务的实现就是这个commit方法,它的作用,要么提交当前事务,要么回滚;
其中,defStatus.isLocalRollbackOnly()变量的实际值:是根据事务传播行为的不同而具备的回滚当前事务或者整个事务的flag;举个栗子,nested事务,回滚的是当前事务,而不影响整体的事务流程;required事务,则表示要回滚的是整个事务流程;
☞ rollback:
该方法的实现逻辑使用伪代码来表示为:
· 是否有节点
有--回滚到当前保存的事务节点
· 是否为新事务
是--回滚当前事务
· 其他情况
· 是否有事务
……
因此,该方法和commit方法是相辅相承的。
☞ handleExistingTransaction :该方法主要是为一个存在的事务创建事务状态;
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {
//如果事务定义中没有事务的隔离级别,抛异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//事务定义中隔离级别为不支持事务
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);
}
//事务隔离级别为开启一个新事务
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 {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
//事务隔离级别为嵌套事务
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.
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;
}
}
// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
if (isValidateExistingTransaction()) {
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)"));
}
}
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);
}
▶ TransactionTemplate
该类继承了DefaultTransactionDefinition,简化了事务的划分和事务异常的处理;在该类中,引用了PlatformTransactionManager,核心方法是execute:
@Override
@Nullable
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
//如果实现了CallbackPreferringPlatformTransactionManager,直接调用execute方法(由于execute方法的出参是泛型,必须有具体类做强转)
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
//如果不是,获取当前事务管理器的事务状态
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
// 这个方法我还没有明确调用关系,待后续!!!!!!!
result = action.doInTransaction(status);
}
catch (RuntimeException | Error ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Throwable ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
▶TransactionStatus:
表示事务的状态,代表一个新建的或者已经存在的事务,控制事务执行和查询事务状态;它是从SavePointManager接口派生的,但需要注意的是:节点管理只对基础的事务管理起作用;
▶ TransactionInterceptor
我们都知道Spring的事务是采用AOP(切面)的方式实现的,提起事务实现我们就不得不提及到TransactionAspectSupport和它的相关类;
TransactionAspectSupport是提供事务切面的抽象类(也可以理解成是一个基础类,比如TransactionInterceptor),该类包括spring的基础事务api;
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
该类实现了BeanFactoryAware和InitializingBean,在该类所定义的每一个方法都有自己的实现,但由于要做切面,它的子类都必须序列化,否则无法使用,因此该类是抽象的;
该类实现的BeanFactoryAware的作用,主要是为了能够使用spring中的bean做配置:
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory var1) throws BeansException;
}
该类中实现的InitializingBean,主要是在bean实例化完成后调用,完成初始化检查,查看当前对象是否完整,是否可用;而对对象的可用性检查则是在afterPropertiesSet方法中完成;
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
作为TransactionAspectSupport的子类,是线程安全的,它按照正确的顺序调用了超类中的方法(比如:invokeWithinTransaction):
@Override
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); //此处调用为超类中的方法
}
TransactionAspectSupport.invokeWithinTransaction 代码如下:
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
//获取事务的属性源
TransactionAttributeSource tas = getTransactionAttributeSource();
//根据事务属性源,获取事务属性(属性是配置的,详见setTransactionAttributes(Properties transactionAttributes)方法)
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 获取事务属性要使用的事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
//获取方法标识,为子类的切面提供调用条件
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
//如果事务属性是空,或者并不是CallbackPreferringPlatformTransactionManager的实现类
//该种情况通常是我们使用的声明式事务的执行逻辑
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//根据事务属性、节点定义信息和事务管理器创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 编程式事务的执行逻辑
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
该篇主要是先对Spring事务中的几个重要类(接口)有个大致的了解,后续将会对它们在Spring事务中的协作进行深入解析;