public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
//当程序执行事务方法的时候会走invoke ,MethodInvocation:方法调用的描述,在方法调用时提供给拦截器
@Override
@Nullable
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);
}
}
该类首先会通过 MethodInvocation(方法调用描述) 得到目标类 ,然后以事务的方式执行方法 invokeWithinTransaction。该方法是其父类的方法
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
/**
-
General delegate for around-advice-based subclasses, delegating to several other template
-
methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
-
as well as regular {@link PlatformTransactionManager} implementations.
-
@param method the Method being invoked
-
@param targetClass the target class that we’re invoking the method on
-
@param invocation the callback to use for proceeding with the target invocation
-
@return the return value of the method, if any
-
@throws Throwable propagated from the target invocation
*/
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
//获取事务属性源:即 @Transactional注解的属性
TransactionAttributeSource tas = getTransactionAttributeSource();
//获取事务属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
//方法名,类名+方法名:如 cn.xx.UserServiceImpl.save
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
//声明式事务处理 @Transactional
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 【标记1】Standard transaction demarcation with getTransaction and commit/rollback calls.
//创建TransactionInfo,事务详情对象,其中包括事务管理器(transactionManager),
//事务属性(transactionAttribute),方法名(joinpointIdentification),事务状态(transactionStatus)
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//【标记2】执行方法,这是一个环绕通知,通常会导致目标对象被调用
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//回滚事务:AfterThrowing
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清理事务
cleanupTransactionInfo(txInfo);
}
//AfterReturning:后置通知,提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It’s a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error(“Application exception overridden by commit exception”, throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) { <