11.2.9.2. トランザクションオブザーバー
トランザクションオブザーバーは、イベントが発生したトランザクションの完了フェーズ前または完了フェーズ後にイベント通知を受け取ります。たとえば、以下のオブザーバーメソッドは、カテゴリーツリーを更新するトランザクションが正常に実行される場合のみアプリケーションコンテキストにキャッシュされたクエリー結果セットを更新します。
public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }
トラザクションオブザーバーには 5 つの種類があります。
- IN_PROGRESS: デフォルトではオブザーバーは即座に呼び出されます。
- AFTER_SUCCESS: トランザクションが正常に完了する場合のみ、オブザーバーはトランザクションの完了フェーズの後に呼び出されます。
- AFTER_FAILURE: トランザクションの完了に失敗する場合のみ、オブザーバーはトランザクションの完了フェーズの後に呼び出されます。
- AFTER_COMPLETION: オブザーバーはトランザクションの完了フェーズの後に呼び出されます。
- BEFORE_COMPLETION: オブザーバーはトランザクションの完了フェーズの前に呼び出されます。
トランザクションオブザーバーは、単一のアトミックトランザクションよりも状態が保持される期間が長いため、トランザクションオブザーバーはステートフルオブジェクトモデルで重要になります。
JPA クエリー結果セットをアプリケーションスコープにキャッシュしたと仮定します。
import javax.ejb.Singleton; import javax.enterprise.inject.Produces; @ApplicationScoped @Singleton public class Catalog { @PersistenceContext EntityManager em; List<Product> products; @Produces @Catalog List<Product> getCatalog() { if (products==null) { products = em.createQuery("select p from Product p where p.deleted = false") .getResultList(); } return products; } }
Product はときどき作成および削除されます。この場合は、製品カタログを更新する必要があります。ただし、この更新を実行する前に、トランザクションが正常に完了するのを待つ必要があります。
Products を作成および削除する Bean は、次のようなイベントをトリガーします。
import javax.enterprise.event.Event; @Stateless public class ProductManager { @PersistenceContext EntityManager em; @Inject @Any Event<Product> productEvent; public void delete(Product product) { em.delete(product); productEvent.select(new AnnotationLiteral<Deleted>(){}).fire(product); } public void persist(Product product) { em.persist(product); productEvent.select(new AnnotationLiteral<Created>(){}).fire(product); } ... }
トランザクションが正常に完了した後に、Catalog がイベントを監視できるようになりました。
import javax.ejb.Singleton; @ApplicationScoped @Singleton public class Catalog { ... void addProduct(@Observes(during = AFTER_SUCCESS) @Created Product product) { products.add(product); } void removeProduct(@Observes(during = AFTER_SUCCESS) @Deleted Product product) { products.remove(product); } }