文章目录
前言
在上一篇Spring源码解读:@Transactional注解是如何生效的里面,我们讲解了咱们这个AOP 的advisor(BeanFactoryTransactionAttributeSourceAdvisor)中的pointCut(TransactionAttributeSourcePointcut)的逻辑,主要靠matches方法来判断advisor是否需要生效。那么今天就来分析下BeanFactoryTransactionAttributeSourceAdvisor中的advice(TransactionInterceptor)的具体执行逻辑。
一、类图

可以看到TransactionInterceptor确实是一个Advice,但是其实Advice和Interceptor这两个接口类,并没有方法需要实现,更像是标志类,或者说是为了实现动态而设计的类。
二、类关系
1. TransactionStatus
public class DefaultTransactionStatus extends AbstractTransactionStatus {
@Nullable
private final Object transaction;
private final boolean newTransaction;
private final boolean newSynchronization;
private final boolean readOnly;
private final boolean debug;
@Nullable
private final Object suspendedResources;
}
其中最重要的就是newTransaction和newSynchronization。分别表示是否是新事务和是否是是否是第一次同步操作。
具体作用:newTransaction的作用比较简单,就是标志当前使用的事务是否是新的事务,具体用在判断是否需要commit;而newSynchronization是用来控制TransactionSynchronizationManager类的init和clear的,只有为true才会进行,同时用来控制钩子函数是否执行。具体有如下的几个钩子函数(AbstractPlatformTransactionManager):
钩子函数1:triggerBeforeCommit
钩子函数2:triggerBeforeCompletion
钩子函数3:triggerAfterCommit
钩子函数4:triggerAfterCompletion
其实正常能够commit的时候执行的时候,钩子函数1和钩子函数2执行只有先后顺序,钩子函数3和钩子函数4执行也只有先后顺序,中间没有插入其他关于事务的逻辑。
newTransaction取值为true或者false的时机好理解
newSynchronization在同一线程内只有第一次调用newTransaction为true的时候,才为true,其余时候都是false
也就是每个加了@Transactional注解的方法,都会对应生成TransactionStatus对象,但是在同一个线程内只有第一个TransactionStatus对象的newSynchronization才为true
三、MethodInterceptor#invoke
1.方法拦截器?
public interface MethodInterceptor extends Interceptor {
/**
* Implement this method to perform extra treatments before and
* after the invocation. Polite implementations would certainly
* like to invoke {@link Joinpoint#proceed()}.
* @param invocation the method invocation joinpoint
* @return the result of the call to {@link Joinpoint#proceed()};
* might be intercepted by the interceptor
* @throws Throwable if the interceptors or the target object
* throws an exception
*/
Object invoke(MethodInvocation invocation) throws Throwable;
}
按照invoke上面这方法的说明,就是该实现应该写成Joinpoint#proceed()的invoke的方法,也就是在joinpoint.proceed()逻辑的前后加上自己的逻辑。例如在基于AOP+Redis实现一个简单的频控拦截器中的拦截方法实现逻辑。
2.TransactionInterceptor#invoke
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);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
// 基于事务来执行被代理的类的方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
可以看到主要实现的是invokeWithTransaction方法
3. TransactionAspectSupport#invokeWithinTransaction
结合上面的类图结构可以看到TransactionInterceptor继承了TransactionAspectSupport,所以TransactionInterceptor#invoke的实际逻辑走的是TransactionAspectSupport#invokeWithinTransaction
咱们只挑重点代码分析。
// 创建事务/获取事务;事务信息txInfo可能为空
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.

本文深入分析了Spring框架中@Transactional注解的执行逻辑,包括类图、类间关系、核心方法TransactionInterceptor#invoke的具体实现等,揭示了如何通过AOP实现事务管理。
最低0.47元/天 解锁文章
758

被折叠的 条评论
为什么被折叠?



