学习这篇博文需要首先明白Spring AOP的实现原理,可以参考Spring的BeanPostProcessor扩展点实现类AbstractAutoProxyCreator和Spring AOP创建代理类之JdkDynamicAopProxy这两篇博文。
TransactionInterceptor
该类是Advice实现类,用于对事务性的方法进行拦截,使用通用 Spring的事务基础类
(PlatformTransactionManager
/ReactiveTransactionManager
)进行声明式事务管理。
-
派生自
{@link TransactionAspectSupport}
类,该类包含与 Spring 的底层事务 API 的集成。 -
TransactionInterceptor 只是以正确的顺序调用相关的超类方法,例如
{@link #invokeWithinTransaction}
。 -
TransactionInterceptors是线程安全的
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
public TransactionInterceptor() {}
/**
* 创建一个新的事务拦截器TransactionInterceptor.
* @param ptm 默认的事务管理器,通过该事务管理器进行实际的事务管理
* @param attributes properties形式的事务属性
*/
public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
setTransactionManager(ptm);
setTransactionAttributes(attributes);
}
/**
* 创建一个新的事务拦截器TransactionInterceptor
* @param ptm 默认的事务管理器,通过该事务管理器进行实际的事务管理
* @param tas 事务属性源TransactionAttributeSource
*/
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
@Override
public Object invoke(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);
//适配到父类TransactionAspectSupport的invokeWithinTransaction方法
//第三个参数是InvocationCallback接口,可以保证在父类TransactionAspectSupport#invokeWithinTransaction方法中回调到当前方法的拦截器链条
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}
TransactionAspectSupport
事务aspect的基类,例如 {@link TransactionInterceptor}
或 AspectJ
aspect。
- 通过策略模式,使用
{@link PlatformTransactionManager}
或{@link ReactiveTransactionManager}
的实现类执行实际的事务管理工作,一个{@link TransactionAttributeSource}
用于一个确定的类或方法的事务定义。 - 如果在
{@link TransactionAttribute}
中没有指定事务名称,则默认名称将是{@code 完全限定的类名 + "." + 方法名}
。
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
//事务信息持有者,支持{@code currentTransactionStatus()}方法,并支持互相协作的不同advice之间的通信(例如,@Before 和@After)
private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
new NamedThreadLocal<>("Current aspect-driven transaction");
//事务管理器名称
@Nullable
private String transactionManagerBeanName;
//事务管理器
@Nullable
private TransactionManager transactionManager;
//事务属性源
@Nullable
private TransactionAttributeSource transactionAttributeSource;
//Bean工厂
@Nullable
private BeanFactory beanFactory;
//TransactionAspectSupport内部接口用于继续进行目标方法调用的简单回调接口
@FunctionalInterface
protected interface InvocationCallback {
Object proceedWithInvocation() throws Throwable;
}
//省略其他代码
currentTransactionInfo
用于返回当前事务信息 TransactionInfo
- 如果实现的子类,不能在一个方法中处理所有的操作,例如一个AspectJ 切面涉及不同的@Before,@After通知,才需要使用这种机制来获取当前的 TransactionInfo。
- 一个@Around通知可以在整个aspect方法中保存对 TransactionInfo 的引用。
- 一个TransactionInfo始终会被返回,即使没有事务被创建,可以通过
TransactionInfo.hasTransaction()
方法查询是否有事务
protected static TransactionInfo currentTransactionInfo() throws NoTransactionException {
return transactionInfoHolder.get();
}
currentTransactionStatus
返回当前方法调用中的事务状态 transaction status,主要用于设置当前事务rollback-only属性
public static TransactionStatus currentTransactionStatus() throws NoTransactionException {
TransactionInfo info = currentTransactionInfo();
if (info == null || info.transactionStatus == null) {
throw new NoTransactionException("No transaction aspect-managed TransactionStatus in scope");
}
return info.transactionStatus;
}
TransactionInfo
TransactionAspectSupport静态内部类,表示事务信息
protected static final class TransactionInfo {
//事务管理器
private final PlatformTransactionManager transactionManager;
//事务属性
private final TransactionAttribute transactionAttribute;
//字符串形式的连接点识别符,也就是事务所作用的方法,如com.aoptx.AServiceImpl.methodA
private final String joinpointIdentification;
//事务状态信息
private TransactionStatus transactionStatus;
@Nullable
private TransactionInfo oldTransactionInfo;
public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,
@Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {
this.transactionManager = transactionManager;
this.transactionAttribute = transactionAttribute;
this.joinpointIdentification = joinpointIdentification;
}
public PlatformTransactionManager getTransactionManager() {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
return this.transactionManager;
}
@Nullable
public TransactionAttribute getTransactionAttribute() {
return this.transactionAttribute;
}
public String getJoinpointIdentification() {
return this.joinpointIdentification;
}
public void newTransactionStatus(@Nullable TransactionStatus status) {
this.transactionStatus = status;
}
@Nullable
public TransactionStatus getTransactionStatus() {
return this.transactionStatus;
}
//返回该aspect是否创建了一个事务
public boolean hasTransaction() {
return (this.transactionStatus != null);
}
//将该事务信息绑定到当前线程
private void bindToThread() {
//暴露当前事务状态TransactionStatus,保存任何已经存在的事务状态,以便在此事务完成后进行恢复
this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);
}
//恢复之前已经存在的事务信息
private void restoreThreadLocalStatus() {
transactionInfoHolder.set(this.oldTransactionInfo);
}
}
invokeWithinTransaction
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
//获取事务属性源TransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
//获取当前调用的方法的事务属性,如果TransactionAttribute为null,则该方法就是非事务方法
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//通过TransactionAttribute获取事务管理器TransactionManager
final TransactionManager tm = determineTransactionManager(txAttr);
//1.ReactiveTransactionManager类型的事务管理器,这个不常用,代码忽略
//2.常用的PlatformTransactionManager事务管理器
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
//连接点识别符,也就是事务所作用的方法,如com.aoptx.AServiceImpl.methodA
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
//创建一个标准的事务,有getTransaction,commit,rollback
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
//调用拦截器链条中的下一个拦截器,最终目标方法会被调用
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 调用出现异常,进行处理
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清除事务信息
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//提交事务commit
commitTransactionAfterReturning(txInfo);
return retVal;
}
//3.CallbackPreferringPlatformTransactionManager类型的事务管理器,不常用,代码忽略
else {
}
}
createTransactionIfNecessary
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable 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;
}
};
}
//从TransactionManager中获取事务,返回TransactionStatus
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//调用抽象父类AbstractPlatformTransactionManger的getTransaction方法
status = tm.getTransaction(txAttr);
}
}
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
prepareTransactionInfo
为给定的属性TransactionAttribute和状态TransactionStatus准备一个 TransactionInfo。
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {
//只要进入到事务方法里,就会创建一个TransactionInfo
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
//
if (txAttr != null) {
txInfo.newTransactionStatus(status);
}
//如果没有事务属性,则不需要创建事务
else {
// The TransactionInfo.hasTransaction() method will return false. We created it only
// to preserve the integrity of the ThreadLocal stack maintained in this class.
if (logger.isTraceEnabled()) {
logger.trace("No need to create transaction for [" + joinpointIdentification +
"]: This method is not transactional.");
}
}
//将TransactionInfo绑定到当前线程,即使我们在这里没有创建一个新的事务
//这保证了TransactionInfo堆栈将被正确管理,即使这个aspect没有创建任何事务。
txInfo.bindToThread();
return txInfo;
}
completeTransactionAfterThrowing
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
//如果事务属性不为空,且事务对该异常ex进行回滚,则调用事务管理器进行事务回滚
//可以通过Transactional注解中rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName配置
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
//调用事务管理器进行事务的回滚
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
throw ex2;
}
}
//如果异常不满足,则进行提交commit,但是如果TransactionStatus.isRollbackOnly()方法被设置为true,那么仍然会回滚
else {
// We don't roll back on this exception.
// Will still roll back if TransactionStatus.isRollbackOnly() is true.
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
throw ex2;
}
}
}
}
commitTransactionAfterReturning
执行事务提交,如果没有事务,则什么也不做
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
//如果事务信息不为null,则进行事务提交
if (txInfo != null && txInfo.getTransactionStatus() != null) {
//委托给具体的TransactionManager进行事务提交
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
扩展学习
- Spring 的注解方式的事务实现机制
- Spring的BeanPostProcessor扩展点实现类AbstractAutoProxyCreator
- Spring AOP创建代理类之JdkDynamicAopProxy
- Spring 的注解方式的事务实现机制
- Spring的TransactionDefinition中定义的事务的传播特性和隔离级别
- [详解Spring的事务管理PlatformTransactionManager](