spring事务-源码分析

129 阅读3分钟

核心步骤

1.入口 //控制器或者dubbo接口方法
2.spring事务拦截器 //后面的源码都是spring事务拦截器
3.service类的业务方法

*入口

应用入口,控制器的方法或dubbo服务的方法。

*spring-CglibAopProxy

class CglibAopProxy implements AopProxy, Serializable {
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
 Object oldProxy = null;
 boolean setProxyContext = false;
 Object target = null;
 TargetSource targetSource = this.advised.getTargetSource();
 try {
  if (this.advised.exposeProxy) {
   // Make invocation available if necessary.
   oldProxy = AopContext.setCurrentProxy(proxy);
   setProxyContext = true;
  }
  // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
  target = targetSource.getTarget();
  Class<?> targetClass = (target != null ? target.getClass() : null);
  List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  Object retVal;
  // Check whether we only have one InvokerInterceptor: that is,
  // no real advice, but just reflective invocation of the target.
  if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
   // We can skip creating a MethodInvocation: just invoke the target directly.
   // Note that the final invoker must be an InvokerInterceptor, so we know
   // it does nothing but a reflective operation on the target, and no hot
   // swapping or fancy proxying.
   Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
   retVal = methodProxy.invoke(target, argsToUse);
  }
  else {
   // We need to create a method invocation...
   retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); //调用
  }
  retVal = processReturnType(proxy, target, method, retVal);
  return retVal;
 }
 finally {
  if (target != null && !targetSource.isStatic()) {
   targetSource.releaseTarget(target);
  }
  if (setProxyContext) {
   // Restore old proxy.
   AopContext.setCurrentProxy(oldProxy);
  }
 }
}

ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
public Object proceed() throws Throwable {
 // We start with an index of -1 and increment early.
 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
  return invokeJoinpoint(); //后调用
 }

 Object interceptorOrInterceptionAdvice =
   this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
  // Evaluate dynamic method matcher here: static part will already have
  // been evaluated and found to match.
  InterceptorAndDynamicMethodMatcher dm =
    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
  Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
  if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
   return dm.interceptor.invoke(this);
  }
  else {
   // Dynamic matching failed.
   // Skip this interceptor and invoke the next in the chain.
   return proceed();
  }
 }
 else {
  // It's an interceptor, so we just invoke it: The pointcut will have
  // been evaluated statically before this object was constructed.
  return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); //先调用
 }
}

事务拦截器TransactionInterceptor

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
@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);
}

父类方法

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
@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.
 TransactionAttributeSource tas = getTransactionAttributeSource();
 final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
 final PlatformTransactionManager tm = determineTransactionManager(txAttr);
 final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

 if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  // Standard transaction demarcation with getTransaction and commit/rollback calls.
  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.
   retVal = invocation.proceedWithInvocation(); //调用
  }
  catch (Throwable ex) {
   // target invocation exception
   completeTransactionAfterThrowing(txInfo, ex);
   throw ex;
  }
  finally {
   cleanupTransactionInfo(txInfo);
  }
  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) {
    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
   }
   throw ex2;
  }
 }
}

CglibAopProxy

class CglibAopProxy implements AopProxy, Serializable {
/**
  * Gives a marginal performance improvement versus using reflection to
  * invoke the target when invoking public methods.
  */
 @Override
 protected Object invokeJoinpoint() throws Throwable {
  if (this.methodProxy != null) {
   return this.methodProxy.invoke(this.target, this.arguments); //调用
  }
  else {
   return super.invokeJoinpoint();
  }
 }
}

MethodProxy

public Object invoke(Object obj, Object[] args) throws Throwable {
 try {
  init();
  FastClassInfo fci = fastClassInfo;
  return fci.f1.invoke(fci.i1, obj, args); //调用
 }
 catch (InvocationTargetException ex) {
  throw ex.getTargetException();
 }
 catch (IllegalArgumentException ex) {
  if (fastClassInfo.i1 < 0)
   throw new IllegalArgumentException("Protected method: " + sig1);
  throw ex;
 }
}

*service类的业务方法

@Transactional(propagation = Propagation.SUPPORTS, transactionManager = "managerTransactionManager") //service类的方法有事务注解,1.先被spring事务拦截器拦截 2.然后才执行service类的业务方法
public List<Country> selectAllCountry() {
 return countryMapper.selectAll();
}

调用栈

invoke:49, MapperProxy (org.apache.ibatis.binding)
selectAll:-1, $Proxy85 (com.sun.proxy)
selectAllCountry:85, QrcodeManagerService (com.xxx.manager.service)
invoke:-1, QrcodeManagerService$$FastClassBySpringCGLIB$$e814fefd (com.xxx.manager.service)
invoke:218, MethodProxy (org.springframework.cglib.proxy)
invokeJoinpoint:749, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:163, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceedWithInvocation:-1, 1684616005 (org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$558)
invokeWithinTransaction:294, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:98, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:186, ReflectiveMethodInvocation (org.springframework.aop.framework)
intercept:688, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
selectAllCountry:-1, QrcodeManagerService$$EnhancerBySpringCGLIB$$b23f7c70 (com.xxx.manager.service)
selectAllCountry:39, QrcodeManager (com.xxx.manager.remoteserver)
invokeMethod:-1, Wrapper1 (com.alibaba.dubbo.common.bytecode)
doInvoke:47, JavassistProxyFactory$1 (com.alibaba.dubbo.rpc.proxy.javassist)
invoke:76, AbstractProxyInvoker (com.alibaba.dubbo.rpc.proxy)
invoke:52, DelegateProviderMetaDataInvoker (com.alibaba.dubbo.config.invoker)
invoke:56, InvokerWrapper (com.alibaba.dubbo.rpc.protocol)
invoke:62, ExceptionFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:75, MonitorFilter (com.alibaba.dubbo.monitor.support)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:42, TimeoutFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:11, AppNameAppendFilter (com.eptok.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:78, TraceFilter (com.alibaba.dubbo.rpc.protocol.dubbo.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:84, AccessLogExtFilter (xxx.qrcode.common.filter.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:82, CatTransaction (com.eptok.log.rpc.dubbo)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:73, ContextFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:112, GenericFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, ClassLoaderFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
invoke:38, EchoFilter (com.alibaba.dubbo.rpc.filter)
invoke:72, ProtocolFilterWrapper$1 (com.alibaba.dubbo.rpc.protocol)
reply:104, DubboProtocol$1 (com.alibaba.dubbo.rpc.protocol.dubbo)
handleRequest:96, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:173, HeaderExchangeHandler (com.alibaba.dubbo.remoting.exchange.support.header)
received:51, DecodeHandler (com.alibaba.dubbo.remoting.transport)
run:57, ChannelEventRunnable (com.alibaba.dubbo.remoting.transport.dispatcher)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)