文章目录
- 【README】
- 【步骤1】UserAppService调用userSupport.saveNewUser()
- 【步骤2】获取到TransactionInterceptor
- 【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法
- 【补充】AopContext作用
- 【步骤4】CglibMethodInvocation#proceed方法
- 【步骤5】调用ReflectiveMethodInvocation#proceed方法(反射方法调用类)
- 【步骤6】调用 TransactionInterceptor#invoke(事务拦截器#invoke方法)
- 【补充】TransactionInterceptor-事务拦截器源码
- 【步骤7】调用TransactionAspectSupport#invokeWithinTransaction方法
- 【步骤8】根据事务属性txAttr获取事务管理器,tm=JdbcTransactionManager
- 【补充】事务管理器是什么?
- 【步骤9】TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑(非常重要)
- 【步骤9.1】按需创建事务-createTransactionIfNecessary()
- 【补充】TransactionInfo事务信息定义
- 【补充】TransactionStatus事务状态定义
- 【步骤9.2】执行目标方法
【README】
1)声明式事务代码样例:
public interface UserMapper {
UserPO qryUserById(@Param("id") String id);
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
void insertUser(UserPO userPO);
}
public interface UserAccountMapper {
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
void insertUserAccount(UserAccountPO userAccountPO);
}
【代码解说】
- 代码调用链路:UserAppService -> userSupport.saveNewUser -> userMapper.insertUser + userAccountMapper.insertUserAccount
- userSupport.saveNewUser 带有 @Transactional 注解; 第1层(最外层)@Transactional标注的方法
- userMapper.insertUser 带有 @Transactional 注解; 第2层@Transactional标注的方法1
- userAccountMapper.insertUserAccount 带有 @Transactional 注解; 第2层@Transactional标注的方法2
2)@Transactional:事务注解,用于定义事务元数据,包括事务管理器名称,事务传播行为,超时时间(单位秒),是否只读,回滚的异常类型;
- @Transactional可以标注类与方法,不管是标注类还是方法,@Transactional标注所在的类的bean都会被spring通过aop代理进行增强;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Reflective
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
String[] label() default {};
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default -1;
String timeoutString() default "";
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
【步骤1】UserAppService调用userSupport.saveNewUser()
1)因为 userSupport中的saveNewUser方法被@Transaction标注,所以该bean被spring增强为aop代理,所以访问aop代理的入口方法intercept(),即CglibAopProxy#DynamicAdvisedInterceptor静态内部类的 intercept方法;
【步骤2】获取到TransactionInterceptor
【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法
chain有一个元素: TransactionInterceptor-事务拦截器;
接着执行 467行:retVal = (new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
【补充】AopContext作用
【补充455行代码】: AopContext实际上是带有ThreadContext的容器对象,用于存储代理对象;
public final class AopContext {
private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal("Current AOP proxy");
private AopContext() {
}
public static Object currentProxy() throws IllegalStateException {
Object proxy = currentProxy.get();
if (proxy == null) {
throw new IllegalStateException("Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.");
} else {
return proxy;
}
}
@Nullable
static Object setCurrentProxy(@Nullable Object proxy) {
Object old = currentProxy.get();
if (proxy != null) {
currentProxy.set(proxy);
} else {
currentProxy.remove();
}
return old;
}
}
【步骤4】CglibMethodInvocation#proceed方法
CglibMethodInvocation#proceed方法, 即Cglib方法调用类#proceed方法 (proceed=继续或进行或处理)
【CglibAopProxy#CglibMethodInvocation】
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
}
// 调用proceed
@Nullable
public Object proceed() throws Throwable {
try {
return super.proceed();
} catch (RuntimeException var2) {
throw var2;
} catch (Exception var3) {
if (!ReflectionUtils.declaresException(this.getMethod(), var3.getClass()) && !KotlinDetector.isKotlinType(this.getMethod().getDeclaringClass())) {
throw new UndeclaredThrowableException(var3);
} else {
throw var3;
}
}
}
}
【步骤5】调用ReflectiveMethodInvocation#proceed方法(反射方法调用类)
调用ReflectiveMethodInvocation#proceed方法, ReflectiveMethodInvocation=反射方法调用类
// ReflectiveMethodInvocation=反射方法调用类
// interceptorsAndDynamicMethodMatcher 是一个列表,包含一个元素 TransactionInterceptor
// currentInterceptorIndex 初始值=-1
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// interceptorOrInterceptionAdvice 就是 TransactionInterceptor ,而不是 InterceptorAndDynamicMethodMatcher
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
return dm.matcher().matches(this.method, targetClass, this.arguments) ? dm.interceptor().invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); // 调用到这里
}
}
}
获取到的interceptorOrInterceptionAdvice的属性如下:
【步骤6】调用 TransactionInterceptor#invoke(事务拦截器#invoke方法)
调用 TransactionInterceptor#invoke(ReflectiveMethodInvocation), 传入的入参this是ReflectiveMethodInvocation-反射方法调用对象(包装了 UserSupportImpl#saveNewUser方法的代理对象)
【TransactionInterceptor#invoke】
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
Method var10001 = invocation.getMethod();
Objects.requireNonNull(invocation);
return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}
上述 invocation::proceed中的invocation实际是 ReflectiveMethodInvocaion-反射方法调用类,ReflectiveMethodInvocaion封装了代理对象proxy,方法method等属性;
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
protected final Object proxy;
@Nullable
protected final Object target;
protected final Method method;
protected Object[] arguments;
@Nullable
private final Class<?> targetClass;
@Nullable
private Map<String, Object> userAttributes;
protected final List<?> interceptorsAndDynamicMethodMatchers;
private int currentInterceptorIndex = -1;
protected ReflectiveMethodInvocation(Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
【补充】TransactionInterceptor-事务拦截器源码
TransactionInterceptor继承自TransactionAspectSupport;
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
public TransactionInterceptor() {
}
public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
this.setTransactionManager(ptm);
this.setTransactionAttributeSource(tas);
}
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
Method var10001 = invocation.getMethod();
Objects.requireNonNull(invocation);
// 调用到这里, 注意最后一个入参是 invocation::proceed;
return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}
private void writeObject(ObjectOutputStream oos) throws IOException {
//...
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// ...
}
}
【步骤7】调用TransactionAspectSupport#invokeWithinTransaction方法
因为TransactionInterceptor 继承自TransactionAspectSupport; 而invokeWithinTransaction方法的最后一个入参invocation就是封装了目标方法,即UserSupportImpl#saveNewUser方法的包装对象ReflectiveMethodInvocation;
获取到的事务管理器类型是 JdbcTransactionManger, 而事务属性TransactionAttribute保存了注解@Transaction标注的方法的元数据,包括事务传播行为,隔离级别,超时时间,是否只读,事务管理器等属性; 而TransactionAttribute继承自TransactionDefinition-事务定义接口;
【TransactionAttribute】事务属性-TransactionAttribute定义
public interface TransactionAttribute extends TransactionDefinition {
@Nullable
String getQualifier();
Collection<String> getLabels();
boolean rollbackOn(Throwable ex);
}
【TransactionAspectSupport#invokeWithinTransaction方法】执行到获取PlatformTransactionManager-平台事务管理器;
【步骤8】根据事务属性txAttr获取事务管理器,tm=JdbcTransactionManager
上述第7步执行到145行,接着判断tm(也就是JdbcTransactionManager)是否是ReactiveTransactionManager类型;
JdbcTransactionManager父类是DataSourceTransactionManager,而DataSourceTransactionManager父类是AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager父类是PlatformTransactionManager;结论:tm(JdbcTransactionManager)不是CallbackPreferringPlatformTransactionManager,所以执行到160行;
又160行得到的ptm还是JdbcTransactionManager,与tm指向同一个对象,162行判断是否为CallbackPreferringPlatformTransactionManager类型不通过,接着执行第220行;
【补充】事务管理器是什么?
public class JdbcTransactionManager extends DataSourceTransactionManager;
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean;
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, ConfigurableTransactionManager, Serializable;
【DataSourceTransactionManager】数据源事务管理器-方法列表
- doBegin-开启事务
- doCommit-提交事务
- doGetTransaction-获取事务
- doResume-恢复事务
- doRollback-回滚事务
- doSuspend-挂起事务;
【DataSourceTransactionManager父类AbstractPlatformTransactionManager】抽象平台事务管理器-部分方法列表
- doBegin 开启事务
- doCommit 提交
- doGetTransation 获取事务
- doResume 恢复事务
- doSuspend 挂起事务
- doRollback 回滚
- setNestedTransactionAllowed -设置允许嵌套事务;
【步骤9】TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑(非常重要)
1)TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑,具体步骤如下(跳过了分支判断):
- 步骤9.1:调用createTransactionIfNecessary方法,创建事务;
- 步骤9.2:调用invocation.proceedWithInvocation(),执行具体业务逻辑(执行目标方法);
- 步骤9.2.1(或有) : 抛出异常,执行completeTransactionAfterThrowing
- 步骤9.3:执行完成(无论是否抛出异常),调用cleanupTransactionInfo()
- 步骤9.4:判断返回值是否不为null 且 事务属性是否不为null
- 步骤9.5:调用commitTransactionAfterReturning(),提交事务;
【TransactionAspectSupport#invokeWithinTransaction()】 在事务中调用;上游是TransactionInterceptor,而TransactionInterceptor是TransactionAspectSupport的子类; 源码如下。
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = this.getTransactionAttributeSource();
TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
TransactionManager tm = this.determineTransactionManager(txAttr);
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager rtm) {
// tm类型是JdbcTransactionManager,所以不会执行到这里
// ...
return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, rtm);
} else {
PlatformTransactionManager ptm = this.asPlatformTransactionManager(tm);
String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
if (txAttr != null && ptm instanceof CallbackPreferringPlatformTransactionManager cpptm) {
// ptm类型是JdbcTransactionManager,所以不会执行到这里
// ...
} else {
// 程序执行到这里
// 1 创建事务,【非常重要】
TransactionInfo txInfo = this.createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 2 通过反射执行具体业务逻辑, invocation就是包装了业务方法UserSuuportImpl#saveUser()方法的调用对象
retVal = invocation.proceedWithInvocation();
} catch (Throwable var22) {
// 2.1 抛出异常 (或有)
this.completeTransactionAfterThrowing(txInfo, var22);
throw var22;
} finally {
// 3 最后清理事务信息
this.cleanupTransactionInfo(txInfo);
}
// 4 判断返回值是否不为null 且 事务属性是否不为null
if (retVal != null && txAttr != null) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null) {
label185: {
if (retVal instanceof Future) {
// 5 若返回值为 Future类型(异步线程执行结果类)
Future<?> future = (Future)retVal;
if (future.isDone()) {
try {
future.get();
} catch (ExecutionException var27) {
if (txAttr.rollbackOn(var27.getCause())) {
status.setRollbackOnly();
}
} catch (InterruptedException var28) {
Thread.currentThread().interrupt();
}
break label185;
}
}
if (vavrPresent && TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {
retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
}
}
// 5 提交事务
this.commitTransactionAfterReturning(txInfo);
return retVal;
}
}
}
【步骤9.1】按需创建事务-createTransactionIfNecessary()
TransactionAspectSupport#createTransactionIfNecessary()详情参见 spring声明式事务原理02-调用第1层@Transactional方法-按需创建事务createTransactionIfNecessary
根据事务管理器+事务属性+aop连接点(切点)创建事务,如下:
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) {
txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) {
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 通过事务管理器获取事务
status = tm.getTransaction((TransactionDefinition)txAttr);
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured");
}
}
// 准备事务信息TransactionInfo
return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status);
}
【补充】TransactionInfo事务信息定义
1)TransactionInfo是TransactionAspectSupport的 静态内部类,是一个聚合类,封装了事务相关的多个组件:
- transactionManager:事务管理器(封装了事务提交,回滚功能)
- TransactionAttribute:事务属性 (@Transaction注解元数据)
- joinpointIdentification:切点标识(被@Transaction标注的目标方法的全限定名称)
- TransactionStatus:事务状态 (封装获取事务状态的方法,如是否只读,是否回滚,是否保存点,事务是否完成,当前线程是否存在事务等)
- oldTransactionInfo-上一个事务信息对象;
其中 oldTransactionInfo-上一个事务信息对象,是bindToThread()方法与restoreThreadLocalStatus() 需要用到的;
protected static final class TransactionInfo {
@Nullable
private final PlatformTransactionManager transactionManager;
@Nullable
private final TransactionAttribute transactionAttribute;
private final String joinpointIdentification;
@Nullable
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;
}
public boolean hasTransaction() {
return this.transactionStatus != null;
}
private void bindToThread() {
this.oldTransactionInfo = (TransactionInfo)TransactionAspectSupport.transactionInfoHolder.get();
TransactionAspectSupport.transactionInfoHolder.set(this);
}
private void restoreThreadLocalStatus() {
TransactionAspectSupport.transactionInfoHolder.set(this.oldTransactionInfo);
}
}
// 事务信息持有器(transactionInfoHolder)是一个ThreadLocal对象,
// 用于保存当前事务信息,及上一个事务信息(挂起时),以便恢复上一个事务信息;
private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
new NamedThreadLocal("Current aspect-driven transaction");
事务信息持有器(transactionInfoHolder):是一个ThreadLocal对象,用于保存当前事务信息,及上一个事务信息(挂起时),以便恢复上一个事务信息;
【补充】TransactionStatus事务状态定义
1)TransactionStatus继承自 TransactionExecution, SavepointManager
2)TransactionStatus封装了事务状态方法,包括是否有保存点,当前线程是否存在事务,当前线程是否存在新事务,是否只读,设置回滚状态或判断是否回滚,事务是否完成等状态方法;
3)封装的事务方法包括:
- 保存点相关方法:包括 hasSavepoint , createSavepoint, rollbackToSavepoint, releaseSavepoint
- 事务相关方法: 包括hasTransaction, isNewTransaction, isReadOnly, setRollbackOnly, isRollbackOnly, isCompleted;
- 嵌套传播模式相关方法:isNested (嵌套模式底层原理是保存点)
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
default boolean hasSavepoint() {
return false;
}
default void flush() {
}
}
// 事务执行
public interface TransactionExecution {
default String getTransactionName() {
return "";
}
default boolean hasTransaction() {
return true;
}
default boolean isNewTransaction() {
return true;
}
default boolean isNested() {
return false;
}
default boolean isReadOnly() {
return false;
}
default void setRollbackOnly() {
throw new UnsupportedOperationException("setRollbackOnly not supported");
}
default boolean isRollbackOnly() {
return false;
}
default boolean isCompleted() {
return false;
}
}
// 保存点管理器
public interface SavepointManager {
Object createSavepoint() throws TransactionException;
void rollbackToSavepoint(Object savepoint) throws TransactionException;
void releaseSavepoint(Object savepoint) throws TransactionException;
}
【步骤9.2】执行目标方法
1)调用 invocation.proceedWithInvocation() 调用目标方法; invocation的类是 CglibMethodInvocation,即cglib代理方法调用类;
2)invocation.proceedWithInvocation():调用CglibMethodInvocation#proceed() 方法,又CglibMethodInvocation是封装了目标方法的cglib方法调用代理对象,所以接着会调用目标方法,即UserSupportImpl#saveNewUser()方法;
3)接着调用父类ReflectiveMethodInvocation的proceed()方法;
4)接着执行ReflectiveMethodInvocation#invokeJoinpoint方法,如下。
5)接着执行 AopUtils#invokeJoinpointUsingReflection() 方法
其中 originalMethod.invoke(target, args) 是通过反射调用具体的目标方法;