• SAStrutsのActionのトランザクション

    2012年03月28日 22時31分
    SAStruts + Mayaaで開発しています。
    まだ実装方法に迷いながらやっているので、考えたことなどをメモっておこうと思います。


    表示用データを作ってHTMLに出力する流れを次のようにしていました。


    まず、Actionに表示用データのフィールドを持ちます。
    リクエストパラメータの設定対象とならないようprivateにしています。
    1private List<Homu> homus;


    privateだとMayaaから参照出来ないため、getterを作成します。
    1public List<Homu> getHomus()
    2{
    3    return homus;
    4}


    そしてMayaaから上記getter経由でデータを読み出します。
    <m:forEach id="homus" items="${homus}" var="homu"/>


    この時、SAStrutsのActionがデフォルトでTxAttributeCustomizerを設定しているため、
    getHomus()メソッドにトランザクションがかかってしまいます。

    このトランザクションは特に必要な物ではないため、消してみようかと思いました。



    解決策1

    動くんだから気にしない。


    解決策2

    publicにしてgetterを使わない。

    チュートリアルなんか見ていると、SAStruts的な正解はpublicにするような気もします。
    1public List<Homu> homus;


    ただ、リクエストパラメータで同じ名前を指定されるとデータが入るのが気になります。
    パラメータ名は外からは推測しか出来ませんし、Actionできちんと上書きすれば問題ないか。


    解決策3

    TxAttributeCustomizerを拡張して、トランザクションが不要なメソッドを対象から外す。

    具体的にはTxAttributeCustomizerを継承し、
    @Executeアノテーションが付いたメソッド以外は除外するクラスを作る。
    1public class ActionTxAttributeCustomizer extends TxAttributeCustomizer
    2{
    3    @Override
    4    protected void doCustomize(final ComponentDef componentDef)
    5    {
    6        final Class<?> componentClass = componentDef.getComponentClass();
    7        final TransactionAttribute classAttribute = componentClass.getAnnotation(TransactionAttribute.class);
    8        final TransactionAttributeType classAttributeType = classAttribute != null ? classAttribute.value() : defaultAttributeType;
    9
    10        for (final Method method : componentClass.getMethods())
    11        {
    12            if (method.isSynthetic() || method.isBridge())
    13                continue;
    14
    15            if (method.getDeclaringClass() == Object.class)
    16                continue;
    17
    18            // @Executeアノテーションが付いていない物は除外する
    19            if (method.getAnnotation(Execute.class) == null)
    20                continue;
    21
    22            final TransactionAttribute methodAttribute = method.getAnnotation(TransactionAttribute.class);
    23            final TransactionAttributeType methodAttributeType = methodAttribute != null ? methodAttribute.value() : classAttributeType;
    24            final String interceptorName = txInterceptors.get(methodAttributeType);
    25            if (!StringUtil.isEmpty(interceptorName))
    26                componentDef.addAspectDef(AspectDefFactory.createAspectDef(interceptorName, method));
    27        }
    28    }
    29}

    「get」から始まるメソッドは除外。とかでもいいかもしれません。



    そこはかとなくこれでいい気がしないことも無くも無いのでこれで行ってみようと思います。