3

基本的には、JMS キューと、JMS キューからメッセージを収集し、それらに対して何らかの処理を行い、JPA を介してメッセージをデータベースに永続化するための MDB があります。メッセージを DB に永続化するメソッドを、新しいトランザクションで開始するようにマークしました。

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void create(T entity)
{
    try
    {
        getEntityManager().persist(entity);
    }
    catch(Exception e)
    {
        throw new RuntimeException("DB Exception");
    }
}

トランザクションがロールバックされた場合、トランザクションが完了するまで自動的に破棄されますか? そうでない場合、それを有効にする方法は?

4

1 に答える 1

4

例外が に伝搬したMDB場合、トランザクションはコミットされず、メッセージは受信確認されず、再試行されます。EJB 3.1 仕様から:

メッセージの受信確認は、コンテナーによって自動的に処理されます。メッセージ駆動型 Bean がコンテナ管理のトランザクション境界を使用する場合、メッセージ確認はトランザクション コミットの一部として自動的に処理されます。

よくわかりませんWeblogicが、メッセージがドロップされるか未配信のキューに入れられるまで、再試行回数、再試行間隔などを設定する JMS キュー パラメータが必要です。

しかし、通常は で例外をキャッチするMDBことをおRuntimeException勧めMDBします。EJB 3.1 仕様から:

一般に、メッセージ駆動型 Bean は RuntimeExceptions をスローすべきではありません。

メッセージ駆動型 Bean クラスのメソッド (メッセージ リスナ メソッドおよびコンテナによって呼び出されるコールバックを含む) からスローされるアプリケーション例外ではない RuntimeException は、「存在しない」状態に遷移します。

たとえば、次のような方がよいでしょう。

public class MyMDB implements MessageListener {

  @Resource
  private MessageDrivenContext context;

  public void onMessage() {
     try {
        //some other processing
        someService.create(entity);
     }
     catch(Exception e) {
        //mark the message as undelivered
        context.setRollbackOnly();
     }
  }
}
于 2013-04-23T18:51:20.973 に答える