0

次のメッセージ駆動型 Bean があり、最初に必要な db ルックアップを実行し (1)、次に外部システムを呼び出します (2) (応答時間は数秒から最大 2 分まで変化する可能性があります)。いくつかの db テーブルを更新します (3)。エンティティマネージャーがどのリソースを保持しているかを理解していないため、次のことが意味があるかどうかを質問します。

  • データベース ルックアップ (1) が完了したら、エンティティ マネージャーを閉じます。
  • 外部システムの応答を受信した後、EntityManagerFactory を使用して新しいエンティティ マネージャーを作成する

さらに、EntityManager インジェクションの代わりに EntityManagerFactory.createEntityManager() を使用する利点があるかどうかを知りたいです。

前もって感謝します

コンテナ: WebLogic Server 10.3.3

MDB コード:

@MessageDriven(
        activationConfig = { @ActivationConfigProperty(
                propertyName = "destinationType", propertyValue = "javax.jms.Queue"
        ) })
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyBean implements MessageListener {

    @Resource
    private MessageDrivenContext context;
    @PersistenceUnit(unitName = "pu1")
    private EntityManagerFactory    emf;

    private static final Logger log = Logger.getLogger(MyBean.class);

    public MyBean() {}

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void onMessage(Message incomingMsg) {
        EntityManager em = null;
        try{
            if(incomingMsg instanceof TextMessage){
                em = this.emf.createEntityManager()
                //perform db lookups (1)
                ...
                em.close()
                //call external system (response time up to 2 min) (2)
                ...
                //db update (3)
                em = this.emf.createEntityManager()
                ...
            } else{
                throw new IllegalArgumentException("Unsupported message type");
            }
        } catch (Exception ex){
            log.error("Message processing failed. Forcing the associated transaction to rollback", ex);
            context.setRollbackOnly();
        } finally{
            if(em != null && em.isOpen()){
                em.close();
            }
        }
    }
}
4

1 に答える 1

0

EntityManager を開いたままにしても問題ありません (実際、仕様では、EntityManager を閉じても、トランザクションがコミットまたはロールバックされるまで永続コンテキストは開いたままになるとされています)。外部システムコールの応答が遅すぎるとタイムアウトになる可能性があるため、代わりにトランザクションについて心配する必要があります。その呼び出しをトランザクションの一部にしたいですか? XAトランザクションですか?それ以外の場合は、コードをリファクタリングして、外部システムへの呼び出しがトランザクションの一部にならないようにする必要があります。

于 2013-02-05T09:09:59.587 に答える