导读
从事务的基础知识到一些核心源码的分析,然后逐步引入到分布式事务的常用解决方案,以及分布式事务核心框架源码的讲解。
(本系列持续更新,感兴趣请关注我的公众号,不错过下一波干货)。
前言
上面一篇已经完成了源码的入门,我们已经知道了核心流程的处理类,本篇开始,我们会逐步完善上一篇中的图。这一篇从事务的开启,到业务逻辑执行,已经事务提交或者回滚的流程进行,梳理完成整个spring事务流程的处理。
知识点
事务开启的源码 业务逻辑执行 事务的提交与回滚
1.主流程回顾
从上篇文章中我们已经知道执行核心业务逻辑的代码如下(隐藏了非核心业务代码):
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)throws Throwable {
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 事务的开启
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// 执行业务逻辑
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
//事务回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//事务提交
commitTransactionAfterReturning(txInfo);
return retVal;
}
}
主要包含4个核心流程
事务的开启:createTransactionIfNecessary 执行业务逻辑:invocation.proceedWithInvocation() 事务的回滚:completeTransactionAfterThrowing(txInfo, ex); 事务的提交:commitTransactionAfterReturning(txInfo);
2.事务处理的核心流程
2.1.事务的开启
我们从上一篇TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification)
作为入口,进行代码的跟踪
protected TransactionInfo createTransactionIfNecessary(
PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
// If no name specified, apply method identification as transaction name.
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//改行代码为核心的开启事务方法,这里的tm是`PlatformTransactionManager`,实际的逻辑是由`AbstractPlatformTransactionManager`来实现的
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
这里的 tm
是PlatformTransactionManager
,事务管理器,核心逻辑由其父类AbstractPlatformTransactionManager
来处理事务的开启经过 TransactionManager
最终还是会调用底层的JDBC
来开启事务,通过beginTransaction()
方法实现

2.2.业务逻辑的执行
核心业务逻辑是通过代理模式去执行invocation.proceedWithInvocation()
如果执行逻辑中出现异常,则走catch流程,调用 completeTransactionAfterThrowing
进行事务的回滚,执行完成后抛出异常,中断,不再走下面的逻辑如执行成功,则 commitTransactionAfterReturning
进行事务的提交
2.3.事务的回滚
若上述业务逻辑执行失败,则回执行catch中的事务回滚代码
completeTransactionAfterThrowing
,并中断下面代码的执行。这一块不再贴代码
我们可以看到整体的流程和开启事务流程基本一致:
都是通过 TM
来处理,经过几个核心组件的调用之后,最终都是通过JDBC
来完成事务的回滚。
2.4.事务的提交
若第二步业务逻辑执行成功,则执行事务提交的代码
commitTransactionAfterReturning
。

我们可以看到整体的流程和事务的回滚流程基本一致:
都是通过 TM
来处理,经过几个核心组件的调用之后,最终都是通过JDBC
来完成事务的提交。
3.Spring事务的设计
我们看到上面的核心流程涉及到了如下几个类,那么我们来研究下这些类有哪些用途。
3.1.核心类
3.1.1.PlatformTransactionManager
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
这里涉及到3个最核心的方法,而我们使用的是该接口的抽象类AbstractPlatformTransactionManager
3.1.2.TransactionDefinition
该类定义了事务的一些属性和定义,其中事务的隔离级别就在该类中实现,上面开启事务的实现需要依赖该类作为参数
3.2.设计思路
spring事务是通过代理模式,在流程中通过TransactionInterceptor
对业务逻辑进行增强实现,其实就是通过Aop的思想来实现。这个在很多的框架中都是这么实现的,这种设计对于代码的侵入性较低。后续我们研究分布式事务组件TCC的时候也会看的这样的使用方式。
关于
更多内容可关注公众号
Github: https://github.com/liangliang1259/common-notes 公众号





