7.10.2. Transactional Observers
트랜잭션 관찰자는 이벤트가 발생한 트랜잭션의 완료 단계 전후에 이벤트 알림을 받습니다. 상태 저장 개체 모델에서는 종종 상태가 단일 원자 트랜잭션보다 긴 동안 유지되기 때문에 트랜잭션 관찰자가 중요합니다.
트랜잭션 관찰자는 5가지가 있습니다.
-
IN_PROGRESS: 기본적으로 관찰자는 즉시 호출됩니다. -
AFTER_SUCCESS: 관찰자는 트랜잭션 완료 단계 이후에 호출되지만 트랜잭션이 성공적으로 완료된 경우에만 호출됩니다. -
AFTER_FAILURE: 트랜잭션 완료 단계 후에 관찰 프로그램이 호출되지만 트랜잭션이 성공적으로 완료되지 않는 경우에만 관찰자가 호출됩니다. -
AFTER_COMPLETION: 관찰자는 트랜잭션 완료 단계 후에 호출됩니다. -
BEFORE_COMPLETION: 관찰자는 트랜잭션 완료 단계 전에 호출됩니다.
다음 observer 메서드는 애플리케이션 컨텍스트에 캐시된 쿼리 결과 집합을 새로 고치지만 카테고리 트리를 업데이트하는 트랜잭션 시에만 캐시됩니다.
public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }다음 예와 같이 애플리케이션 범위에 설정된 Jakarta Persistence 쿼리 결과를 캐시했다고 가정합니다.
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;
}
}
경우에 따라 제품이 생성 또는 삭제 되는 경우도 있습니다. 이 경우 제품 카탈로그를 새로 고쳐야 합니다. 그러나 이 업데이트를 수행하기 전에 트랜잭션이 성공적으로 완료될 때까지 기다려야 합니다.
다음은 Products triggers 이벤트를 생성하고 삭제하는 빈의 예입니다.
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);
}
}