@Transactionalアノテーションにつけたクラスは何があった


@Transactionalアノテーションにつけたクラス、プロキシクラスを作った

掲示板サンプルアプリケーションを見て、クラスinfo.saladlam.example.spring.noticeboard.service.MessageServiceImpl@Transactionalアノテーションがつけた。BeanFactoryはこのクラスを処理、org.springframework.transaction.interceptor.TransactionInterceptorがつけたプロキシクラスを作った。下の図はEclipseデバッガで本物のMessageServiceインスタンスが示された。

TransactionInterceptorの役目

  1. トランザクション開始と終了の意図がPlatformTransactionManagerインスタンスに伝えること
  2. 例外処理

下のコードはメソードorg.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(Method, Class<?>, InvocationCallback)の一部。

// ...
        // 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 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(Method, Class<?>, InvocationCallback) 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;
            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;
        }
// ...

プログラムが

retVal = invocation.proceedWithInvocation();

を実行するとき、info.saladlam.example.spring.noticeboard.service.MessageServiceImplのメソードが呼ばれる。

PlatformTransactionManagerの役目

Spring FrameworkのコンテキストのなかにシングルトンPlatformTransactionManagerインスタンスがある。ここに示したサンプルアプリケーションはorg.springframework.jdbc.datasource.DataSourceTransactionManagerという実作。このインスタンスはすべてのトランザクションに関する請求を処理する。