3

メソッドに REQUIRE_NEW のアノテーションを付けましたが、それが新しいトランザクションで実行されることを期待していました。コードは次のとおりです。

public class EJBAImpl implements EJBA {
    @EJB
    private EJBB ejbb;

    public void someMethod(entity){
        ejbb.create(entity);
        //doMoreStuff
    }
}

public class BaseEJB {
    public void create(Entity entity) {
        //saveHere
    }
}

public class EJBBImpl extends BaseEJB implements EJBB {
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void create(Entity entity) {
        super.create(entity);
    }
}

ただし、create メソッドの呼び出し (doMoreStuff と言う場所) の後の行にブレークポイントを配置すると、エンティティが DB に保存されません。私は何が欠けていますか?確認したところ、EJBB はプロキシです。

編集:メソッドが継承されている場合、それは機能しません。解決策は、次のように EJBB のメソッドを変更することでした。

public class EJBBImpl extends BaseEJB implements EJBB {

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void anotherNameForCreate(Entity entity) {
        super.create(entity);
    }
}

別のクラスのメソッドをオーバーライドすると機能しない理由を知っている人はいますか?

4

2 に答える 2

4

@TransactionAttribute には、ejb3.1 仕様のセクション 13.3.7.1 で説明されているように、特別なルールがあります。

Bean クラスにスーパークラスがある場合、次の追加ルールが適用されます。

1) スーパークラス S で指定されたトランザクション属性は、S で定義されたビジネス メソッドに適用されます。S でクラス レベルのトランザクション属性が指定されていない場合は、S で TransactionAttribute(REQUIRED) を指定することと同じです。

2) クラス S で定義されたビジネス メソッド M にトランザクション属性を指定して、クラス S で明示的または暗黙的に指定されたトランザクション属性値をメソッド M に対してオーバーライドすることができます。

3) クラス S のメソッド M が、S のスーパークラスによって定義されたビジネス メソッドをオーバーライドする場合、M のトランザクション属性は、クラス S に適用される上記の規則によって決定されます。

私の理解によると、あなたは 3 番目のポイントにいるため、ejb コンテナーの場合、実際のトランザクション属性は REQUIRES_NEW ではなく @REQUIERED です。

于 2013-06-29T04:22:10.387 に答える
0

RequiresNewアノテーションの留意点

  1. コンテナは、トランザクション属性が NEW トランザクション コンテキストで RequiresNew に設定されているエンタープライズ Bean メソッドを呼び出す必要があります。

  2. クライアントがトランザクション コンテキストに関連付けられていないときに、クライアントがエンタープライズ Bean のメソッドを呼び出すと、コンテナは、メソッド呼び出しをエンタープライズ Bean ビジネス メソッドに委譲する前に、新しいトランザクションを自動的に開始します。コンテナは、ビジネス メソッドによってアクセスされるすべてのリソース マネージャをトランザクションに自動的に登録します。

  3. ビジネス メソッドが他のエンタープライズ Bean を呼び出す場合、コンテナは呼び出しでトランザクション コンテキストを渡します。ビジネス メソッドが完了すると、コンテナはトランザクションのコミットを試みます。コンテナーは、メソッドの結果がクライアントに送信される前にコミット プロトコルを実行します。

  4. クライアントがトランザクション コンテキストを使用して呼び出す場合、コンテナは、新しいトランザクションを開始してビジネス メソッドを呼び出す前に、トランザクション コンテキストと現在のスレッドとの関連付けを中断します。ビジネス メソッドと新しいトランザクションが完了した後、コンテナーは中断されたトランザクションの関連付けを再開します。

解決

別のBeanからEJB参照でメソッドを呼び出した場合のみ、新しいトランザクションが作成されます。同じ Bean 内で create を呼び出しても、新しいトランザクションは生成されません。そのため、別の Bean から呼び出す必要があります。

于 2013-07-01T17:08:09.537 に答える