修缮之前的博文

pull/28/head
AmyliaY 5 years ago
parent dd753a604b
commit 49b7bef419

@ -1,6 +1,7 @@
## 1 事务处理的编程式使用
```java
TransactionDefinition td = new DefaultTransactionDefinition();
// transactionManager 是某一个具体的 PlatformTransactionManager实现类 的对象
TransactionStatus ts = transactionManager.getTransaction(td);
try {
// 这里是需要进行事务处理的方法调用
@ -11,15 +12,14 @@
}
transactionManager.commit(ts);
```
在使用编程式事务处理的过程中利用DefaultTransactionDefinition对象来持有事务处理属性。同时在创建事务的过程中得到一个TransactionStatus对象然后通过直接调用transactionManager的commit()和rollback()方法来完成事务处理。在这个编程式使用事务管理的
过程中没有看到框架特性的使用非常简单和直接很好地说明了事务管理的基本实现过程以及在Spring事务处理实现中涉及一些主要的类比如TransationStatus、TransactionManager等对这些类的使用与声明式事务处理的最终实现是一样的。
在使用编程式事务处理的过程中,利用 DefaultTransactionDefinition对象 来持有事务处理属性。同时,在创建事务的过程中得到一个 TransactionStatus对象然后通过直接调用 transactionManager对象 的 commit() 和 rollback()方法 来完成事务处理。在这个编程式使用事务管理的过程中,没有看到框架特性的使用,非常简单和直接,很好地说明了事务管理的基本实现过程,以及在 Spring事务处理实现 中涉及一些主要的类,比如 TransationStatus、TransactionManager 等,对这些类的使用与声明式事务处理的最终实现是一样的。
与编程式使用事务管理不同在使用声明式事务处理的时候因为涉及Spring框架对事务处理的统一管理以及对并发事务和事务属性的处理所以采用的是一个比较复杂的处理过程但复杂归复杂这个过程对使用声明式事务处理的应用来说基本上是不可见的而是由Spring框架来完成的。有了这些背景铺垫和前面对AOP封装事务处理的了解下面来看看Spring是如何提供声明式事务处理的Spring在这个相对较为复杂的过程中封装了什么。这层封装包括在事务处理中事务的创建、提交和回滚等比较核心的操作。
与编程式使用事务管理不同,在使用声明式事务处理的时候,因为涉及 Spring框架 对事务处理的统一管理,以及对并发事务和事务属性的处理,所以采用的是一个比较复杂的处理过程,但复杂归复杂,这个过程对使用声明式事务处理的应用来说,基本上是不可见的,而是由 Spring框架 来完成的。有了这些背景铺垫和前面对 AOP封装事务处理 的了解,下面来看看 Spring 是如何提供声明式事务处理的Spring 在这个相对较为复杂的过程中封装了什么。这层封装包括在事务处理中事务的创建、提交和回滚等比较核心的操作。
## 2 事务的创建
作为声明式事务处理实现的起始点需要注意TransactionInterceptor拦截器的invoke()回调中使用的createTransactionIfNecessary()方法这个方法是在TransactionInterceptor的基类TransactionAspectSupport中实现的。为了了解这个方法的实现先分析一下TransactionInterceptor的基类实现TransactionAspectSupport并以这个方法的实现为入口了解Spring是如何根据当前的事务状态和事务属性配置完成事务创建的。
作为声明式事务处理实现的起始点,需要注意 TransactionInterceptor拦截器 invoke()回调 中使用的 createTransactionIfNecessary()方法,这个方法是在 TransactionInterceptor 的基类 TransactionAspectSupport 中实现的。为了了解这个方法的实现,先分析一下 TransactionInterceptor 的基类实现 TransactionAspectSupport并以这个方法的实现为入口了解 Spring 是如何根据当前的事务状态和事务属性配置完成事务创建的。
这个TransactionAspectSupport的createTransactionIfNecessary()方法作为事务创建的入口其具体的实现时序如下图所示。在createTransactionIfNecessary()方法的调用中会向AbstractTransactionManager执行getTransaction()方法这个获取Transaction事务对象的过程在AbstractTransactionManager实现中需要对事务的情况做出不同的处理然后创建一个TransactionStatus并把这个TransactionStatus设置到对应的TransactionInfo中去同时将TransactionInfo和当前的线程绑定从而完成事务的创建过程。createTransactionIfNeccessary()方法调用中可以看到两个重要的数据对象TransactionStatus和TransactionInfo的创建这两个对象持有的数据是事务处理器对事务进行处理的主要依据对这两个对象的使用贯穿着整个事务处理的全过程。
这个 TransactionAspectSupport createTransactionIfNecessary()方法 作为事务创建的入口,其具体的实现时序如下图所示。在 createTransactionIfNecessary()方法 的调用中,会向 AbstractTransactionManager 执行 getTransaction()方法,这个获取 Transaction事务对象 的过程,在 AbstractTransactionManager实现 中需要对事务的情况做出不同的处理,然后,创建一个 TransactionStatus并把这个 TransactionStatus 设置到对应的 TransactionInfo 中去,同时将 TransactionInfo 和当前的线程绑定从而完成事务的创建过程。createTransactionIfNeccessary()方法 调用中,可以看到两个重要的数据对象 TransactionStatus TransactionInfo 的创建,这两个对象持有的数据是事务处理器对事务进行处理的主要依据,对这两个对象的使用贯穿着整个事务处理的全过程。
![avatar](images/springTransaction/调用createTransactionIfNecessary()方法的时序图.png)
@ -30,8 +30,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
*/
@Deprecated
protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
// 根据给定的方法和类获取TransactionAttribute
// 如果TransactionAttribute为空则该方法是非事务性的
// 根据给定的方法和类获取 TransactionAttribute
// 如果 TransactionAttribute 为空,则该方法是非事务性的
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
// 使用确定的事务管理器
PlatformTransactionManager tm = determineTransactionManager(txAttr);
@ -39,7 +39,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
}
/**
* 根据给定的TransactionAttribute创建事务
* 根据给定的 TransactionAttribute 创建事务
*/
@SuppressWarnings("serial")
protected TransactionInfo createTransactionIfNecessary(
@ -55,13 +55,13 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
};
}
// TransactionStatus封装了事务执行的状态信息
// TransactionStatus 封装了事务执行的状态信息
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 根据定义好的事务方法配置信息TransactionAttribute通过
// 平台事务管理器PlatformTransactionManager创建事务同时返回
// TransactionStatus来记录当前的事务状态包括已经创建的事务
// 根据定义好的 事务方法配置信息TransactionAttribute通过
// 平台事务管理器 PlatformTransactionManager 创建事务,同时返回
// TransactionStatus 来记录当前的事务状态,包括已经创建的事务
status = tm.getTransaction(txAttr);
}
else {
@ -71,7 +71,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
}
}
}
// 准备TransactionInfoTransactionInfo对象封装了事务处理的配置信息以及TransactionStatus
// 准备 TransactionInfoTransactionInfo对象 封装了事务处理的配置信息以及 TransactionStatus
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
@ -83,9 +83,9 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
// 为TransactionInfo设置TransactionStatusTransactionStatus持有管理事务处理
// 为 TransactionInfo 设置 TransactionStatusTransactionStatus 持有管理事务处理
// 需要的数据transaction对象
// 如果不兼容的TX已经存在事务管理器将标记错误
// 如果不兼容的 TX 已经存在,事务管理器将标记错误
txInfo.newTransactionStatus(status);
}
else {
@ -94,9 +94,9 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
"]: This method isn't transactional.");
}
// 这里把当前的TransactionInfo与线程绑定同时在TransactionInfo中由一个变量来保存以前
// 的TransactionInfo这样就持有了一连串与事务处理相关的TransactionInfo
// 虽然不一定要创建新的事务但总会在请求事务时创建TransactionInfo
// 这里把当前的 TransactionInfo 与线程绑定,同时在 TransactionInfo 中由一个变量来保存以前
// 的 TransactionInfo这样就持有了一连串与事务处理相关的 TransactionInfo
// 虽然不一定要创建新的事务,但总会在请求事务时创建 TransactionInfo
txInfo.bindToThread();
return txInfo;
}
@ -104,426 +104,443 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
```
在以上的处理过程之后,可以看到,具体的事务创建可以交给事务处理器来完成。在事务的创建过程中,已经为事务的管理做好了准备,包括记录事务处理状态,以及绑定事务信息和线程等。下面到事务处理器中去了解一下更底层的事务创建过程。
createTransactionIfNecessary()方法通过调用PlatformTransactionManager的getTransaction()方法生成一个TransactionStatus对象封装了底层事务对象的创建。可以看到AbstractPlatformTransactionManager提供了创建事务的模板这个模板会被具体的事务处理器所使用。从下面的代码中可以看到AbstractPlatformTransactionManager会根据事务属性配置和当前进程绑定的事务信息对事务是否需要创建怎样创建 进行一些通用的处理然后把事务创建的底层工作交给具体的事务处理器完成。尽管具体的事务处理器完成事务创建的过程各不相同但是不同的事务处理器对事务属性和当前进程事务信息的处理都是相同的在AbstractPlatformTransactionManager中完成了该实现这个实现过程是Spring提供统一事务处理的一个重要部分。
createTransactionIfNecessary()方法 通过调用 PlatformTransactionManager getTransaction()方法,生成一个 TransactionStatus对象封装了底层事务对象的创建。可以看到AbstractPlatformTransactionManager 提供了创建事务的模板这个模板会被具体的事务处理器所使用。从下面的代码中可以看到AbstractPlatformTransactionManager 会根据事务属性配置和当前进程绑定的事务信息,对事务是否需要创建,怎样创建 进行一些通用的处理,然后把事务创建的底层工作交给具体的事务处理器完成。尽管具体的事务处理器完成事务创建的过程各不相同,但是不同的事务处理器对事务属性和当前进程事务信息的处理都是相同的,在 **AbstractPlatformTransactionManager** 中完成了该实现,这个实现过程是 Spring 提供统一事务处理的一个重要部分。
```java
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
//---------------------------------------------------------------------
// PlatformTransactionManager的实现
//---------------------------------------------------------------------
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
// doGetTransaction()是抽象方法Transaction对象的取得由具体的事务管理器
// 实现比如DataSourceTransactionManager
Object transaction = doGetTransaction();
// 缓存debug标志以避免重复检查
boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
// 如果没有给出事务定义,则使用默认值
definition = new DefaultTransactionDefinition();
}
// 检查当前线程是否已经存在事务,如果已经存在事务,则根据事务属性中定义的 事务传播属性配置
// 来处理事务的产生
if (isExistingTransaction(transaction)) {
// 对当前线程中已经有事务存在的情况进行处理结果封装在TransactionStatus中
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// 检查definition中timeout属性的设置
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// 当前没有事务存在,这时需要根据事务属性设置来创建事务
// 这里可以看到对事务传播属性配置的处理比如MANDATORY、REQUIRED、REQUIRES_NEW、NESTED等
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对象封装了事务执行情况
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 创建事务由具体的事务管理器来完成DataSourceTransactionManager、HibernateTransactionManager
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}
catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
else {
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
//---------------------------------------------------------------------
// 实现了 PlatformTransactionManager接口 的方法
// 这里用了一个 模板方法模式doGetTransaction(), doBegin() 都是交由子类实现的抽象方法
//---------------------------------------------------------------------
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
// doGetTransaction() 是抽象方法Transaction对象 的取得由具体的事务管理器
// 实现比如DataSourceTransactionManager
Object transaction = doGetTransaction();
// 缓存 debug标志以避免重复检查
boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
// 如果没有给出事务定义,则使用默认值
definition = new DefaultTransactionDefinition();
}
// 检查当前线程是否已经存在事务,如果已经存在事务,则根据事务属性中定义的 事务传播属性配置
// 来处理事务的产生
if (isExistingTransaction(transaction)) {
// 对当前线程中已经有事务存在的情况进行处理,结果封装在 TransactionStatus
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// 检查 definition 中 timeout属性 的设置
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// 当前没有事务存在,这时需要根据事务属性设置来创建事务
// 这里可以看到对事务传播属性配置的处理比如MANDATORY、REQUIRED、REQUIRES_NEW、NESTED等
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对象封装了事务执行情况
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 创建事务由具体的事务管理器来完成DataSourceTransactionManager、HibernateTransactionManager
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException ex) {
resume(null, suspendedResources);
throw ex;
}
catch (Error err) {
resume(null, suspendedResources);
throw err;
}
}
else {
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
}
```
从上面的代码中可以看到AbstractTransactionManager提供的创建事务的实现模板在这个模板的基础上具体的事务处理器需要定义自己的实现来完成底层的事务创建工作比如需要实现isExistingTransaction()和doBegin()方法。关于这些由具体事务处理器实现的方法会在下面结合具体的事务处理器实现DataSourceTransactionManager、HibernateTransactionManager进行分析。
从上面的代码中可以看到AbstractTransactionManager 提供的创建事务的实现模板,在这个模板的基础上,具体的事务处理器需要定义自己的实现来完成底层的事务创建工作,比如需要实现 isExistingTransaction() doBegin()方法。关于这些由具体事务处理器实现的方法会在下面结合具体的事务处理器实现DataSourceTransactionManager、HibernateTransactionManager进行分析。
事务创建的结果是生成一个TransactionStatus对象 通过这个对象来保存事务处理需要的基本信息这个对象与前面提到过的TransactionInfo对象联系在一起 TransactionStatus是TransactionInfo的一个属性然后会把TransactionInfo保存在ThreadLocal对象里这样当前线程可以通过ThreadLocal对象取得TransactionInfo以及与这个事务对应的TransactionStatus对象从而把事务的处理信息与调用事务方法的当前线程绑定起来。在AbstractPlatformTransactionManager创建事务的过程中可以看到TransactionStatus的创建过程。
事务创建的结果是生成一个 TransactionStatus对象 通过这个对象来保存事务处理需要的基本信息,这个对象与前面提到过的 TransactionInfo对象 联系在一起, TransactionStatus TransactionInfo 的一个属性,然后会把 TransactionInfo 保存在 ThreadLocal对象 里,这样当前线程可以通过 ThreadLocal对象 取得 TransactionInfo以及与这个事务对应的 TransactionStatus对象从而把事务的处理信息与调用事务方法的当前线程绑定起来。在 AbstractPlatformTransactionManager 创建事务的过程中,可以看到 TransactionStatus 的创建过程。
```java
/**
* 通过给定的参数创建一个TransactionStatus实例
*/
protected DefaultTransactionStatus newTransactionStatus(
TransactionDefinition definition, Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, Object suspendedResources) {
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
// 这里判断是不是新事务,如果是新事务,需要把事务属性存放到当前线程中
// TransactionSynchronizationManager维护了一系列的ThreadLocal变量
// 来保持事务属性,比如,并发事务隔离级别,是否有活跃的事务等
boolean actualNewSynchronization = newSynchronization &&
!TransactionSynchronizationManager.isSynchronizationActive();
// 把结果记录在DefaultTransactionStatus对象中并返回
return new DefaultTransactionStatus(
transaction, newTransaction, actualNewSynchronization,
definition.isReadOnly(), debug, suspendedResources);
}
/**
* 通过给定的参数,创建一个 TransactionStatus实例
*/
protected DefaultTransactionStatus newTransactionStatus(
TransactionDefinition definition, Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, Object suspendedResources) {
// 这里判断是不是新事务,如果是新事务,需要把事务属性存放到当前线程中
// TransactionSynchronizationManager 维护了一系列的 ThreadLocal变量
// 来保持事务属性,比如,并发事务隔离级别,是否有活跃的事务等
boolean actualNewSynchronization = newSynchronization &&
!TransactionSynchronizationManager.isSynchronizationActive();
// 把结果记录在 DefaultTransactionStatus对象 中并返回
return new DefaultTransactionStatus(
transaction, newTransaction, actualNewSynchronization,
definition.isReadOnly(), debug, suspendedResources);
}
}
```
新事务的创建是比较好理解的这里需要根据事务属性配置进行创建。所谓创建首先是把创建工作交给具体的事务处理器来完成比如DataSourceTransactionManager把创建的事务对象在TransactionStatus中保存下来然后将其他的事务属性和线程ThreadLocal变量进行绑定。
新事务的创建是比较好理解的,这里需要根据事务属性配置进行创建。所谓创建,首先是把创建工作交给具体的事务处理器来完成,比如 DataSourceTransactionManager把创建的事务对象在 TransactionStatus 中保存下来,然后将其他的事务属性和 线程ThreadLocal变量 进行绑定。
相对于创建全新事务的另一种情况是在创建当前事务时线程中已经有事务存在了。这种情况同样需要处理在声明式事务处理中在当前线程调用事务方法的时候就会考虑事务的创建处理这个处理在方法handleExistingTransaction()中完成。这里对现有事务的处理会涉及事务传播属性的具体处理比如PROPAGATION_NOT_SUPPORTED、PROPAGATION_ REQUIRES_ NEW等。
相对于创建全新事务的另一种情况是:在创建当前事务时,线程中已经有事务存在了。这种情况同样需要处理,在声明式事务处理中,在当前线程调用事务方法的时候,就会考虑事务的创建处理,这个处理在方法 handleExistingTransaction() 中完成。这里对现有事务的处理,会涉及事务传播属性的具体处理,比如 PROPAGATION_NOT_SUPPORTED、PROPAGATION_ REQUIRES_ NEW等。
```java
/**
* 为存在的事务创建一个TransactionStatus实例
*/
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) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
// 注意这里的参数transaction为nullnewTransaction为false这意味着事务方法不需要
// 放在事务环境中执行同时挂起事务的信息记录也保存在TransactionStatus中这里包括了
// 进程ThreadLocal对事务信息的记录
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
// PROPAGATION_REQUIRES_NEW表示 新建事务,如果当前存在事务,把当前事务挂起
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);
// 挂起事务的信息记录保存在TransactionStatus中这里包括了进程ThreadLocal对事务信息的记录
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
catch (Error beginErr) {
resumeAfterBeginException(transaction, suspendedResources, beginErr);
throw beginErr;
}
}
// PROPAGATION_NESTED表示 如果当前存在事务则在嵌套事务内执行。如果当前没有事务则执行与PROPAGATION_REQUIRED类似的操作
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()) {
// 在spring管理的事务中 创建事务保存点
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
}
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
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");
}
}
}
// 返回DefaultTransactionStatus注意 第三个参数false 代表当前事务方法没有使用新的事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
/**
* 为存在的事务创建一个 TransactionStatus实例
*/
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) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
// 注意这里的参数transaction 为 nullnewTransaction 为 false这意味着事务方法不需要
// 放在事务环境中执行,同时挂起事务的信息记录也保存在 TransactionStatus 中,这里包括了
// 进程ThreadLocal 对事务信息的记录
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
// PROPAGATION_REQUIRES_NEW 表示 新建事务,如果当前存在事务,把当前事务挂起
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);
// 挂起事务的信息记录保存在 TransactionStatus 中,这里包括了 进程ThreadLocal 对事务信息的记录
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
catch (Error beginErr) {
resumeAfterBeginException(transaction, suspendedResources, beginErr);
throw beginErr;
}
}
// PROPAGATION_NESTED 表示 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
// 则执行与 PROPAGATION_REQUIRED 类似的操作
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()) {
// 在 Spring 管理的事务中 创建事务保存点
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
}
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");
}
}
}
// 返回 DefaultTransactionStatus注意 第三个参数false 代表当前事务方法没有使用新的事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
}
```
## 3 事务的挂起
事务的挂起牵涉线程与事务处理信息的保存,下面看一下事务挂起的实现。
```java
/**
* 挂起给定的事务。先挂起事务同步然后委托给doSuspend()模板方法,
* 该方法返回的SuspendedResourcesHolder对象会作为参数传递给TransactionStatus
*/
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);
}
// 这里在线程中保存与事务处理有关的信息并重置线程中相关的ThreadLocal变量
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);
}
// 若doSuspend()方法出现RuntimeException异常或Error错误则初始的事务依然存在
catch (RuntimeException ex) {
doResumeSynchronization(suspendedSynchronizations);
throw ex;
}
catch (Error err) {
doResumeSynchronization(suspendedSynchronizations);
throw err;
}
}
else if (transaction != null) {
Object suspendedResources = doSuspend(transaction);
return new SuspendedResourcesHolder(suspendedResources);
}
else {
return null;
}
}
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
/**
* 挂起给定的事务。先挂起事务同步,然后委托给 doSuspend()方法,子类一般会重写该方法。
* 该方法返回的 SuspendedResourcesHolder对象会作为参数传递给 TransactionStatus
*/
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);
}
// 这里在线程中保存与事务处理有关的信息,并重置线程中相关的 ThreadLocal变量
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);
}
// 若doSuspend()方法出现RuntimeException异常或Error错误则初始的事务依然存在
catch (RuntimeException ex) {
doResumeSynchronization(suspendedSynchronizations);
throw ex;
}
catch (Error err) {
doResumeSynchronization(suspendedSynchronizations);
throw err;
}
}
else if (transaction != null) {
Object suspendedResources = doSuspend(transaction);
return new SuspendedResourcesHolder(suspendedResources);
}
else {
return null;
}
}
}
```
基于以上内容,就可以完成声明式事务处理的创建了。声明式事务处理能使事务处理应用的开发变得简单,但是简单的背后,蕴含着平台付出的许多努力。
## 4 事务的提交
下面来看看事务提交是如何实现的。有了前面的对事务创建的分析下面来分析一下在Spring中声明式事务处理的事务提交是如何完成的。事务提交的调用入口是TransactionInteceptor的invoke()方法事务提交的具体实现则在其基类TransactionAspectSupport的commitTransactionAfterReturning(TransactionInfo txInfo)方法中。可以看到txInfo是TransactionInfo对象这个参数TransactionInfo对象是
创建事务时生成的。同时Spring的事务管理框架生成的TransactionStatus对象就包含在TransactionInfo对象中。这个commitTransactionAfterReturning()方法在TransactionInteceptor的实现部分是比较简单的它通过直接调用事务处理器来完成事务提交。
下面来看看事务提交是如何实现的。有了前面的对事务创建的分析,下面来分析一下在 Spring 中,声明式事务处理的事务提交是如何完成的。事务提交的调用入口是 TransactionInteceptor 的 invoke()方法,事务提交的具体实现则在其基类 TransactionAspectSupport 的 commitTransactionAfterReturning(TransactionInfo txInfo)方法 中,其中的参数 txInfo 是创建事务时生成的。同时Spring 的事务管理框架生成的 TransactionStatus对象 就包含在 TransactionInfo对象 中。这个 commitTransactionAfterReturning()方法 在 TransactionInteceptor 的实现部分是比较简单的,它通过直接调用事务处理器来完成事务提交。
```java
/**
* 在事务方法成功调用后执行,若出现异常,则不执行。如果不创建事务,则不执行任何操作。
*/
protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
/**
* 在事务方法成功调用后执行,若出现异常,则不执行。如果不创建事务,则不执行任何操作。
*/
protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
}
```
与前面分析事务的创建过程一样我们需要到事务管理器中去看看事务是如何提交的。同样在AbstractPlatformTransactionManager中也有一个模板方法支持具体的事务管理器对事务提交的实现在AbstractPlatformTransactionManager中这个模板方法的实现与前面我们看到的getTransaction()很类似。
与前面分析事务的创建过程一样,我们需要到事务管理器中去看看事务是如何提交的。同样,在 AbstractPlatformTransactionManager 中也有一个模板方法支持具体的事务管理器对事务提交的实现,这个模板方法的实现与前面我们看到的 getTransaction() 很像
```java
/**
* 处理实际提交的事务
*/
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
// 事务提交的准备工作由具体的事务管理器来完成
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
boolean globalRollbackOnly = false;
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
globalRollbackOnly = status.isGlobalRollbackOnly();
}
// 嵌套事务的处理
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
status.releaseHeldSavepoint();
}
// 如果当前事务是一个新事务调用具体事务处理器的doCommit()实现;否则,
// 不提交,由已经存在的事务来完成提交
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
// 该实现由具体的事务管理器来完成
doCommit(status);
}
// 如果我们有一个全局仅回滚标记但仍然没有从commit中获得相应的异常
// 则抛出UnexpectedRollbackException
if (globalRollbackOnly) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, ex);
throw ex;
}
catch (Error err) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, err);
throw err;
}
// 触发器afterCommit()回调,其中抛出的异常已传播到调用方,但该事务仍被视为已提交
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
}
finally {
cleanupAfterCompletion(status);
}
}
/**
* 处理实际提交的事务,这是一个模板方法,其中的 doCommit() 是一个交由子类实现的抽象方法
*/
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
// 事务提交的准备工作由具体的事务管理器来完成
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
boolean globalRollbackOnly = false;
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
globalRollbackOnly = status.isGlobalRollbackOnly();
}
// 嵌套事务的处理
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
status.releaseHeldSavepoint();
}
// 如果当前事务是一个新事务,调用具体事务处理器的 doCommit() 实现;否则,
// 不提交,由已经存在的事务来完成提交
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
// 该实现由具体的事务管理器来完成
doCommit(status);
}
// 如果我们有一个全局仅回滚标记,但仍然没有从 commit 中获得相应的异常,
// 则抛出 UnexpectedRollbackException
if (globalRollbackOnly) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, ex);
throw ex;
}
catch (Error err) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, err);
throw err;
}
// 触发器 afterCommit()回调,其中抛出的异常已传播到调用方,但该事务仍被视为已提交
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
cleanupAfterCompletion(status);
}
}
}
```
可以看到事务提交的准备都是由具体的事务处理器来实现的。当然对这些事务提交的处理需要通过对TransactionStatus保存的事务处理的相关状态进行判断。提交过程涉及AbstractPlatformTransactionManager中的doCommit()和prepareForCommit()方法,它们都是抽象方法,都在具体的事务处理器中完成实现,在下面对具体事务处理器的实现原理的分析中,可以看到对这些实现方法的具体分析。
可以看到,事务提交的准备都是由具体的事务处理器来实现的。当然,对这些事务提交的处理,需要通过对 TransactionStatus 保存的事务处理的相关状态进行判断。提交过程涉及 AbstractPlatformTransactionManager 中的 doCommit() prepareForCommit()方法,它们都是抽象方法,都在具体的事务处理器中完成实现,在下面对具体事务处理器的实现原理的分析中,可以看到对这些实现方法的具体分析。
## 5 事务的回滚
除了事务的创建、挂起和提交外,再来看一看事务的回滚是如何完成的。回滚处理和事务提交非常相似。
```java
/**
* 处理实际的事务回滚
*/
private void processRollback(DefaultTransactionStatus status) {
try {
try {
triggerBeforeCompletion(status);
// 嵌套事务的回滚处理
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
// 当前事务调用方法中,新建事务的回滚处理
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);
}
// 当前事务调用方法中,没有新建事务的回滚处理
else if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
doSetRollbackOnly(status);
}
// 由线程中的前一个事务来处理回滚,这里不执行任何操作
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
}
catch (RuntimeException ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
catch (Error err) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw err;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}
finally {
cleanupAfterCompletion(status);
}
}
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
/**
* 处理实际的事务回滚
*/
private void processRollback(DefaultTransactionStatus status) {
try {
try {
triggerBeforeCompletion(status);
// 嵌套事务的回滚处理
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
}
// 当前事务调用方法中,新建事务的回滚处理
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);
}
// 当前事务调用方法中,没有新建事务的回滚处理
else if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
doSetRollbackOnly(status);
}
// 由线程中的前一个事务来处理回滚,这里不执行任何操作
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
}
catch (RuntimeException ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
catch (Error err) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw err;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}
finally {
cleanupAfterCompletion(status);
}
}
}
```
以上对事务的创建、提交和回滚的实现原理进行了分析,这些过程的实现都比较复杂,一方面 这些处理会涉及很多事务属性的处理;另一方面 会涉及事务处理过程中状态的设置,同时在事务处理的过程中,有许多处理也需要根据相应的状态来完成。这样看来,在实现事务处理的基本过程中就会产生许多事务处理的操作分支。
但总的来说在事务执行的实现过程中作为执行控制的TransactionInfo对象和TransactionStatus对象特别值得我们注意比如它们如何与线程进行绑定如何记录事务的执行情况等。如果大家在配置事务属性时有什么疑惑不妨直接看看这些事务属性的处理过程通过对这些实现原理的了解可以极大地提高对这些事务处理属性使用的理解程度。
但总的来说,在事务执行的实现过程中,作为执行控制的 TransactionInfo对象 TransactionStatus对象 特别值得我们注意,比如它们如何与线程进行绑定,如何记录事务的执行情况等。如果大家在配置事务属性时有什么疑惑,不妨直接看看这些事务属性的处理过程,通过对这些实现原理的了解,可以极大地提高对这些事务处理属性使用的理解程度。

@ -1,21 +1,16 @@
## 1 Spring事务处理的应用场景
下面我们以DataSourceTransactionManager事务管理器为例看一下在具体的事务管理器中如何实现事务创建、提交和回滚这些底
层的事务处理操作。DataSourceTransationManager和其他事务管理器一样如JtaTransactionManagerJpaTransactionManager和JdoTransactionManager都继承自AbstractPlatformManager作为一个基类AbstractPlatfromManager封装了Spring事务处理中通用的处理部分比如事务的创建、提交、回滚事务状态和信息的处理与线程的绑定等有了这些通用处理的支持对于具体的事务管理器而言它们只需要处理和具体数据源相关的组件设置就可以了比如在HibernateTransactionManager中就只需要配置好和Hibnernate事务处理相关的接口以及相关的设置。所以从PlatformTransactionManager组件的设计关系上我们也可以看到Spring事务处理的主要过程是分两个部分完成的通用的事务处理框架是在AbstractPlatformManager中完成而Spring的事务接口与数据源实现的接口多半是由具体
的事务管理器来完成它们都是作为AbstractPlatformManager的子类来是使用的。
下面,我们以 DataSourceTransactionManager事务管理器 为例看一下在具体的事务管理器中如何实现事务创建、提交和回滚这些底层的事务处理操作。DataSourceTransationManager 和其他事务管理器一样,如 JtaTransactionManagerJpaTransactionManager 和 JdoTransactionManager都继承自 AbstractPlatformManager作为一个基类AbstractPlatfromManager 封装了 Spring事务处理 中通用的处理部分,比如事务的创建、提交、回滚,事务状态和信息的处理,与线程的绑定等,有了这些通用处理的支持,对于具体的事务管理器而言,它们只需要处理和具体数据源相关的组件设置就可以了,比如在 HibernateTransactionManager 中,就只需要配置好和 Hibnernate事务处理 相关的接口以及相关的设置。所以,从 PlatformTransactionManager组件 的设计关系上我们也可以看到Spring事务处理 的主要过程是分两个部分完成的,通用的事务处理框架是在 AbstractPlatformManager 中完成,而 Spring 的事务接口与数据源实现的接口,多半是由具体的事务管理器来完成,它们都是作为 AbstractPlatformManager 的子类来是使用的。
可以看到在PlatformTransactionManager组件的设计中 通过PlatformTransactionManager接口 设计了一系列与事务处理息息相关的接口方法如getTransaction()、commit()、rollback()这些和事务处理相关的统一接口。对于这些接口的实现很大一部分是由AbstractTransactionManager抽象类来完成的这个类中的doGetTransaction()、doCommit()等方法和PlatformTransactionManager的方法
对应实现的是事务处理中相对通用的部分。在这个AbstractPlatformManager下为具体的数据源配置了不同的事务处理器以处理不同数据源的事务处理从而形成了一个从抽象到具体的事务处理中间平台设计使应用通过声明式事务处理即开即用事务处理服务隔离那些与特定的数据源相关的具体实现。
可以看到,在 PlatformTransactionManager组件 的设计中 ,通过 PlatformTransactionManager接口 设计了一系列与事务处理息息相关的接口方法,如 getTransaction()、commit()、rollback() 这些和事务处理相关的统一接口。对于这些接口的实现,很大一部分是由 AbstractTransactionManager抽象类 来完成的,这个类中的 doGetTransaction()、doCommit() 等方法和 PlatformTransactionManager 的方法对应,实现的是事务处理中相对通用的部分。在这个 AbstractPlatformManager 下,为具体的数据源配置了不同的事务处理器,以处理不同数据源的事务处理,从而形成了一个从抽象到具体的事务处理中间平台设计,使应用通过声明式事务处理,即开即用事务处理服务,隔离那些与特定的数据源相关的具体实现。
![avatar](/images/springTransaction/PlatformTransactionManager组件的设计.png)
## 2 DataSourceTransactionManager的实现
我们先看一下DataSourceTransactionManager在这个事务管理器中它的实现直接与事务处理的底层实现相关。在事
务开始的时候会调用doBegin()方法首先会得到相对应的Connection然后可以根据事务设置的需要对Connection的相关属性进行配置比如将Connection的autoCommit功能关闭并对像TimeoutInSeconds这样的事务处理参数进行设置最后通过TransactionSynchronizationManager来对资源进行绑定。
我们先看一下 DataSourceTransactionManager在这个事务管理器中它的实现直接与事务处理的底层实现相关。在事务开始的时候会调用 doBegin()方法,首先会得到相对应的 Connection然后可以根据事务设置的需要对 Connection 的相关属性进行配置,比如将 Connection 的 autoCommit功能 关闭,并对像 TimeoutInSeconds 这样的事务处理参数进行设置,最后通过 TransactionSynchronizationManager 来对资源进行绑定。
从下面的代码中可以看到DataSourceTransactionManager作为AbstractPlatformTransactionManager的子类在AbstractPlatformTransactionManager中已经为事务实现设计好了一系列的模板方法比如 事务的提交、回滚处理等。在DataSourceTransactionManager中 可以看到对模板方法中一些抽象方法的具体实现。例如由DataSourceTransactionManager的doBegin()方法实现负责事务的创建工作。具体来说如果使用DataSource创建事务最终通过设置Connection的autoCommit属性来对事务处理进行配置。在实现过程中需要把数据库的Connection和当前的线程进行绑定。对于事务的提交和回滚都是通过直接调用Connection的提交和回滚来完成的在这个实现过程中如何取得事务处理场景中的Connection对象也是一个值得注意的地方。
从下面的代码中可以看到DataSourceTransactionManager 作为 AbstractPlatformTransactionManager 的子类,在 AbstractPlatformTransactionManager 中已经为事务实现设计好了一系列的模板方法,比如 事务的提交、回滚处理等。在 DataSourceTransactionManager 中, 可以看到对模板方法中一些抽象方法的具体实现。例如,由 DataSourceTransactionManager doBegin()方法 实现负责事务的创建工作。具体来说,如果使用 DataSource 创建事务,最终通过设置 Connection autoCommit属性 来对事务处理进行配置。在实现过程中,需要把数据库的 Connection 和当前的线程进行绑定。对于事务的提交和回滚,都是通过直接调用 Connection 的提交和回滚来完成的,在这个实现过程中,如何取得事务处理场景中的 Connection对象也是一个值得注意的地方。
上面介绍了使用DataSourceTransactionManager实现事务创建、提交和回滚的过程基本上与单独使用Connection实现事务处理是一样的也是通过设置autoCommit属性调用Connection的commit()和rollback()方法来完成的。而我们在声明式事务处理中看到的那些事务处理属性并不在DataSourceTransactionManager中完成这和我们在前面分析中看到的是一致的。
上面介绍了使用 DataSourceTransactionManager 实现事务创建、提交和回滚的过程,基本上与单独使用 Connection 实现事务处理是一样的,也是通过设置 autoCommit属性调用 Connection 的 commit() 和 rollback()方法 来完成的。而我们在声明式事务处理中看到的那些事务处理属性,并不在 DataSourceTransactionManager 中完成,这和我们在前面分析中看到的是一致的。
![avatar](/images/springTransaction/PlatformTransactionManager组件的设计.png)
@ -23,20 +18,20 @@
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
/** 这时注入的DataSource */
/** 持有 javax.sql.DataSource对象 */
private DataSource dataSource;
/**
* 这里是产生Transaction的地方为Transaction的创建提供服务对数据库而言
* 事务工作是由Connection来完成的。这里把数据库的Connection对象放到了ConnectionHolder中
* 然后封装到一个DataSourceTransactionObject对象中在这个封装过程中增加了许多为事务处理服务的
* 这里是产生 Transaction对象 的地方,为 Transaction 的创建提供服务,对数据库而言,
* 事务工作是由 Connection 来完成的。这里把数据库的 Connection对象 放到了 ConnectionHolder 中,
* 然后封装到一个 DataSourceTransactionObject对象 中,在这个封装过程中增加了许多为事务处理服务的
* 控制数据
*/
@Override
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
// 获取与当前线程绑定的数据库Connection这个Connection在第一个事务开始
// 获取与当前线程绑定的 数据库Connection这个 Connection 在第一个事务开始
// 的地方与线程绑定
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
@ -45,7 +40,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
}
/**
* 判断是否存在活跃的事务由ConnectionHolder的transactionActive属性来控制
* 判断是否存在活跃的事务,由 ConnectionHolder transactionActive属性 来控制
*/
@Override
protected boolean isExistingTransaction(Object transaction) {
@ -54,8 +49,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
}
/**
* 这里是处理事务开始的地方
* 此实现设置隔离级别,但忽略超时
* 这里是处理事务开始的地方,在这里设置隔离级别,但忽略超时
*/
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
@ -78,7 +72,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 这里是数据库Connection完成事务处理的重要配置需要把autoCommit属性关掉
// 这里是 数据库Connection 完成事务处理的重要配置,需要把 autoCommit属性 关掉
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
@ -93,7 +87,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// 把当前的数据库Connection与线程绑定
// 把当前的 数据库Connection 与线程绑定
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
}
@ -110,7 +104,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
*/
@Override
protected void doCommit(DefaultTransactionStatus status) {
// 取得Connection以后通过Connection进行提交
// 取得 Connection 以后通过Connection 进行提交
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
@ -125,7 +119,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
}
/**
* 事务提交的具体实现通过Connection对象的rollback()方法实现
* 事务提交的具体实现,通过 Connection对象 rollback()方法 实现
*/
@Override
protected void doRollback(DefaultTransactionStatus status) {
@ -143,23 +137,22 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
}
}
```
上面介绍了使用DataSourceTransactionManager实现事务创建、提交和回滚的过程基本上与单独使用Connection实现事务处理是一样的也是通过设置autoCommit属性调用Connection的commit()和rollback()方法来完成的。看到这里,大家一定会觉得非常的熟悉。而
我们在声明式事务处理中看到的那些事务处理属性并不在DataSourceTransactionManager中完成这和我们在前面分析中看到的是一致的。
上面介绍了使用 DataSourceTransactionManager 实现事务创建、提交和回滚的过程,基本上与单独使用 Connection 实现事务处理是一样的,也是通过设置 autoCommit属性调用 Connection 的 commit() 和 rollback()方法 来完成的。看到这里,大家一定会觉得非常的熟悉。而我们在声明式事务处理中看到的那些事务处理属性,并不在 DataSourceTransactionManager 中完成,这和我们在前面分析中看到的是一致的。
## 3 小结
总体来说从声明式事务的整个实现中我们看到声明式事务处理完全可以看成是一个具体的Spring AOP应用。从这个角度来看Spring事 务处理的实现本身就为应用开发者提供了一个非常优秀的AOP应用参考实例。在Spring的声明式事务处理中采用了IoC容器的Bean配置为事务方法调用提供事务属性设置从而为应用对事务处理的使用提供方便。
总体来说,从声明式事务的整个实现中我们看到,声明式事务处理完全可以看成是一个具体的 Spring AOP应用。从这个角度来看Spring事务处理 的实现本身就为应用开发者提供了一个非常优秀的 AOP应用 参考实例。在 Spring 的声明式事务处理中,采用了 IoC容器 Bean配置 为事务方法调用提供事务属性设置,从而为应用对事务处理的使用提供方便。
有了声明式的使用方式可以把对事务处理的实现与应用代码分离出来。从Spring实现的角度来看声明式事务处理的大致实现过程是这样的在为事务处理配置好AOP的基础设施(比如对应的Proxy代理对象和事务处理Interceptor拦截器对象)之后首先需要完成对这些事务属性配置的读取这些属性的读取处理是在TransactionInterceptor中实现的在完成这些事务处理属性的读取之后Spring为事务处理的具体实现做好了准备。可以看到Spring声明式事务处理的过程同时也是一个整合事务处理实现到Spring AOP和IoC容器中去的过程。我们在整个过程中可以看到下面一些要点在这些要点中体现了对Spring框架的基本特性的灵活使用。
- 如何封装各种不同事务处理环境下的事务处理具体来说作为应用平台的Spring它没法对应用使用什么样的事务处理环境做出限制这样对应用户使用的不同的事务处理器Spring事务处理平台都需要为用户提供服务。这些事务处理实现包括在应用中常见的DataSource的Connection、Hibermate的Transaction等Spring事务处理通过一种统一的方式把它们封装起来从而实现一个通用的事务处理过程实现这部分事务处理对应用透明使应用即开即用。
有了声明式的使用方式,可以把对事务处理的实现与应用代码分离出来。从 Spring实现 的角度来看,声明式事务处理的大致实现过程是这样的:在为事务处理配置好 AOP 的基础设施(比如,对应的 Proxy代理对象 事务处理Interceptor拦截器对象)之后,首先需要完成对这些事务属性配置的读取,这些属性的读取处理是在 TransactionInterceptor 中实现的在完成这些事务处理属性的读取之后Spring 为事务处理的具体实现做好了准备。可以看到Spring声明式事务处理 的过程同时也是一个整合事务处理实现到 Spring AOP IoC容器 中去的过程。我们在整个过程中可以看到下面一些要点,在这些要点中,体现了对 Spring框架 的基本特性的灵活使用。
- 如何封装各种不同事务处理环境下的事务处理,具体来说,作为应用平台的 Spring它没法对应用使用什么样的事务处理环境做出限制这样对应用户使用的不同的事务处理器Spring事务处理平台 都需要为用户提供服务。这些事务处理实现包括在应用中常见的 DataSource Connection、Hibermate Transaction等Spring事务处理 通过一种统一的方式把它们封装起来,从而实现一个通用的事务处理过程,实现这部分事务处理对应用透明,使应用即开即用。
- 如何读取事务处理属性值,在事务处理属性正确读取的基础上,结合事务处理代码,从而完成在既定的事务处理配置下,事务处理方法的实现。
- 如何灵活地使用Spring AOP框架对事务处理进行封装提供给应用即开即用的声明式事务处理功能。
- 如何灵活地使用 Spring AOP框架对事务处理进行封装提供给应用即开即用的声明式事务处理功能。
在这个过程中有几个Spring事务处理的核心类是我们需要关注的。其中包括TransactionInterceptor它是使用AOP实现声明式事务处理的拦截器封装了Spring对声明式事务处理实现的基本过程还包括TransactionAttributeSource和TransactionAttribute这两个类它们封装了对声明式事务处理属性的识别以及信息的读入和配置。我们看到的TransactionAttribute对象可以视为对事务处理属性的数据抽象如果在使用声明式事务处理的时候应用没有配置这些属性Spring将为用户提供DefaultTransactionAttribute对象该对象提供了默认的事务处理属性设置。
在这个过程中,有几个 Spring事务处理 的核心类是我们需要关注的。其中包括 **TransactionInterceptor**,它是使用 AOP 实现声明式事务处理的拦截器,封装了 Spring 对声明式事务处理实现的基本过程;还包括 TransactionAttributeSource **TransactionAttribute** 这两个类,它们封装了对声明式事务处理属性的识别,以及信息的读入和配置。我们看到的 TransactionAttribute对象可以视为对事务处理属性的数据抽象如果在使用声明式事务处理的时候应用没有配置这些属性Spring 将为用户提供 DefaultTransactionAttribute对象该对象提供了默认的事务处理属性设置。
在事务处理过程中可以看到TransactionInfo和TransactionStatus这两个对象它们是存放事务处理信息的主要数据对象它们通过与线程的绑定来实现事务的隔离性。具体来说TransactionInfo对象本身就像是一个栈对应着每一次事务方法的调用它会保存每一次事务方法调用的事务处理信息。值得注意的是在TransactionInfo对象中它持有TransactionStatus对象这个TransactionStatus是非常重要的。由这个TransactionStatus来掌管事务执行的详细信息包括具体的事务对象、事务执行状态、事务设置状态等。
在事务处理过程中,可以看到 **TransactionInfo** **TransactionStatus** 这两个对象它们是存放事务处理信息的主要数据对象它们通过与线程的绑定来实现事务的隔离性。具体来说TransactionInfo对象 本身就像是一个栈,对应着每一次事务方法的调用,它会保存每一次事务方法调用的事务处理信息。值得注意的是,在 TransactionInfo对象 中,它持有 TransactionStatus对象这个 TransactionStatus 是非常重要的。由这个 TransactionStatus 来掌管事务执行的详细信息,包括具体的事务对象、事务执行状态、事务设置状态等。
在事务的创建、启动、提交和回滚的过程中都需要与这个TransactionStatus对象中的数据打交道。在准备完这些与事务管理有关的数据之后具体的事务处理是由事务处理器TransactionManager来完成的。在事务处理器完成事务处理的过程中与具体事务处理器无关的操作都被封装到AbstractPlatformTransactionManager中实现了。这个抽象的事务处理器为不同的具体事务处理器提供了通用的事务处理模板它封装了在事务处理过程中与具体事务处理器无关的公共的事务处理部分。我们在具体的事务处理器(比如DataSourceTransactionManager和HibernateTransactionManager)的实现中可以看到,最为底层的事务创建、挂起、提交、回滚操作。
在事务的创建、启动、提交和回滚的过程中,都需要与这个 TransactionStatus对象 中的数据打交道。在准备完这些与事务管理有关的数据之后,具体的事务处理是由 事务处理器TransactionManager 来完成的。在事务处理器完成事务处理的过程中,与具体事务处理器无关的操作都被封装到 AbstractPlatformTransactionManager 中实现了。这个抽象的事务处理器为不同的具体事务处理器提供了通用的事务处理模板,它封装了在事务处理过程中,与具体事务处理器无关的公共的事务处理部分。我们在具体的事务处理器(比如 DataSourceTransactionManager HibernateTransactionManager)的实现中可以看到,最为底层的事务创建、挂起、提交、回滚操作。
在Spring中也可以通过编程式的方法来使用事务处理器以帮助我们处理事务。在编程式的事务处理使用中, TransactionDefinition是定义事务处理属性的类。对于事务处理属性Spring还提供了一个默认的事务属性DefaultTransactionDefinition来供用户使用。这种事务处理方式在实现上看起来比声明式事务处理要简单但编程式实现事务处理却会造成事务处理与业务代码的紧密耦合因而不经常被使用。在这里我们之所以举编程式使用事务处理的例子是因为通过了解编程式事务处理的使用可以清楚地了解Spring统一实现事务处理的大致过程。
Spring 中,也可以通过编程式的方法来使用事务处理器,以帮助我们处理事务。在编程式的事务处理使用中, TransactionDefinition 是定义事务处理属性的类。对于事务处理属性Spring 还提供了一个默认的事务属性 DefaultTransactionDefinition 来供用户使用。这种事务处理方式在实现上看起来比声明式事务处理要简单,但编程式实现事务处理却会造成事务处理与业务代码的紧密耦合,因而不经常被使用。在这里,我们之所以举编程式使用事务处理的例子,是因为通过了解编程式事务处理的使用,可以清楚地了解 Spring 统一实现事务处理的大致过程。
有了这个背景结合对声明式事务处理实现原理的详细分析比如在声明式事务处理中使用AOP对事务处理进行封装对事务属性配置进行的处理与线程绑定从而处理事务并发并结合事务处理器的使用等能够在很大程度上提高我们对整个Spring事务处理实现的理解。
有了这个背景,结合对声明式事务处理实现原理的详细分析,比如在声明式事务处理中,使用 AOP 对事务处理进行封装,对事务属性配置进行的处理,与线程绑定从而处理事务并发,并结合事务处理器的使用等,能够在很大程度上提高我们对整个 Spring事务处理实现 的理解。
Loading…
Cancel
Save