0

私はCMTによるJTAの境界を完全に理解しようとしています。私が経験している動作は、メソッドの最初の@TransactionAttributeのみがEJBで尊重され、異なる@TransactionAttributeアノテーションを持つ同じBeanの後続のメソッド呼び出しは尊重されないということです。

例:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Foo implements IFoo {

   @EJB
   private IBar barBean;

   // inherits class transaction annotation of NOT_SUPPORTED
   public void doSomething() {
        barBean.doAction();
   }
}

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Bar implements IBar {

    public void doAction() {
        Entity entity = bar.find();
        entity.setName("new name");
        // fails with EJBException with TransactionRequiredException as cause
        save(entity);
    }

    public Entity find() {
        // return some persisted entity.
        return em.findById(1);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Entity save(entity) {
        em.persist(em.merge(entity));
        em.flush();
    }
}

私が見ている動作は、Bar.save()がTransactionRequiredExceptionをスローすることです。したがって、これは、save()に設定されたREQUIREDアノテーションがトランザクションを作成しないことを示しています。REQUIRES_NEWも機能しません。save()を別のEJBに移動すると、期待どおりに機能します。

これは、異なるアノテーション値を使用した同じメソッドの後続の呼び出しに関係なく、最初のTransactionAttributeアノテーションのみが尊重されることを意味しますか?これはバグですか、それとも予想される動作ですか?これを具体的に説明しているドキュメントが見つからないようです。これについての洞察に感謝します。

私のスタック:EJB 3.0、Toplink Essentials、GF V2UR2

4

1 に答える 1

2

私がEJB3仕様を読んだのは、個々のメソッドのトランザクション仕様が、EJB全体のトランザクション仕様をオーバーライドするということです。したがって、REQUIREDが適用されるべきであるというあなたの期待は合理的であるように思われますが、...

これは、BeanメソッドをEJBとして使用している場合のみです。あるビジネスメソッドdoAction()から別のsave()を直接呼び出す場合、EJB参照を使用していないため、これは単なる古いJavaです。コンテナは関与しないため、コンテナが介入する機会はありません。 。

必要なオプションをdoAction()メソッドに適用すると、これが機能することが期待されます。

この理論は、別のEJBへのリファクタリングの効果に関する調査結果と一致しています。

于 2009-10-08T17:04:51.557 に答える