22

次のセットアップでは、メソッド B は (新しい) トランザクションで実行されますか?

メソッド A とメソッド B の 2 つのメソッドを持つ EJB

public class MyEJB implements SessionBean
    public void methodA() {
       doImportantStuff();
       methodB();
       doMoreImportantStuff();
    }

    public void methodB() {
       doDatabaseThing();
    }
}

EJB はコンテナー管理であり、requires_new トランザクションには methodB があり、required トランザクションにはメソッド A があります。したがって:

<container-transaction id="MethodTransaction_1178709616940">
  <method id="MethodElement_1178709616955">
    <ejb-name>MyName</ejb-name>
    <method-name>*</method-name>
  <trans-attribute>Required</trans-attribute>
  </method>
  <method id="MethodElement_1178709616971">
    <ejb-name>MyName</ejb-name>
    <method-name>methodB</method-name>
  </method>
  <trans-attribute>RequiresNew</trans-attribute>
</container-transaction>

ここで、別の EJB が EJB メソッド呼び出しで methodA を呼び出します。methodA がトランザクションで実行されるようになりました。methodA からの methodB への後続の呼び出しは、同じトランザクションで実行されますか、それとも新しいトランザクションで実行されますか? (注意してください、これは実際のコードです。メソッド B への明示的な ejb 呼び出しはありません)

4

3 に答える 3

39

へのmethodB()呼び出しはメソッドの通常の呼び出しであり、EJB コンテナーによってインターセプトされません。実行時に、EJB コンテナはクラスのインスタンスではなくプロキシを注入します。これは、メソッドを呼び出す前に呼び出しをインターセプトして環境を設定する方法です。使用するthis場合は、プロキシ経由ではなく直接メソッドを呼び出しています。したがって、EJB インターフェースを介した呼び出し用に ejb-jar.xml で定義されている内容に関係なく、両方のメソッドが同じトランザクションを使用します。

于 2009-01-09T10:09:51.643 に答える
23

SessionContext を注入し、プロキシ インスタンスを要求します。

@Stateless
public class UserFacade implements UserFacadeLocal {
    @Resource
    private SessionContext context;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    private void create(User user) {
        System.out.println("Users Count: "+count()); //invocation#1
        System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public int count() {
        return ((Long) q.getSingleResult()).intValue();
    }
}

「invocation#1」では、これはローカル呼び出しであり、プロキシを通過せず、カウントを返します

'invocation#2' では、これはプロキシ経由の呼び出しであるため、トランザクションをサポートしないように注釈を付けます (現在は create(user) メソッドによって開かれています)。この呼び出しはトランザクション例外をスローします。

javax.ejb.EJBException: グローバル トランザクションで EJB を呼び出すことはできません

于 2012-09-08T12:11:38.750 に答える
4

それらは同じトランザクションを使用します。

よく覚えていれば、メソッドが呼び出される「前」にコンテナによってトランザクションが開始され、「終了」後にコミットされます。

「a」は「b」を呼び出すため、「b」は同じトランザクションを使用します。

:S

あなたができる最善のことは、それを検証するためにテストすることだと思います! :)

于 2009-01-09T09:22:03.313 に答える