@Transactional注解事务管理的底层实现脉络,就是使用拦截器。它就是TransactionInterceptor。
TransactionInterceptor是继承于TransactionAspectSupport的拦截器,拦截器的原理在这里就不细说了。被@Transactional注解的方法会被TransactionInterceptor拦截,
其invoke方法被调用,最终会调用父类TransactionAspectSupport的invokeWithinTransaction方法。
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); }
ransactionAspectSupport
TransactionAspectSupport的最重要方法是invokeWithinTransaction方法,以下代码块是源码中截取的,已经省略了有回调功能的CallbackPreferringPlatformTransactionManager实现逻辑,这里只阐述非回调的事务管理。
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; } //省略下面CallbackPreferringPlatformTransactionManager的实现逻辑 //...... }
从invokeWithinTransaction方法的源码中,我们可以看到熟悉的影子。completeTransactionAfterThrowing方法对应于jdbc事务管理中的conn.rollBack()方法,而commitTransactionAfterReturning则对应conn.commitTX()方法,那么获取连接、开启事务在哪里呢?其实就在createTransactionIfNecessary方法里。
我们还注意到invokeWithinTransaction方法里有个invocation.proceedWithInvocation()方法的调用,可以看看源码中的描述:
// This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked.
可以知道这个方法的作用是调用拦截器链中的下一个拦截器(涉及到spring拦截器的知识不再在这里赘述),最终返回的是被@Transactional注解的方法的返回值。这个方法被try-catch包围了,其实这方法可以类比于jdbc事务管理中的执行的一系列CRUD方法。