2012-12-13 5 views
0

Java EE (WebSpere), JPA, EJB3, JMS (MDB), JSF와 같은 기술 스택이 있습니다.Singleton 데몬, MDB 및 웹 컨트롤러와 EJB (및 EntityManager) 간의 단방향 연결

아키텍처 : JMS 메시지가 (MDB를 통해) 도착하고 (EntityManager를 사용하여) 지속 된 엔터티로 등록됩니다. 이러한 엔티티의 처리를 담당하는 무한 루프가있는 Singleton 클래스가 있습니다. Singleton은 MDB에 의해 생성 된 엔티티에 대한 알림을받습니다. 초기 엔티티는 싱글 톤 내부의 큐에 저장됩니다. 생성 된 엔티티는 최대 몇 분까지 처리 할 수 ​​있습니다. 특정 양의 엔티티 만 동시에 처리 될 수 있습니다 (Singleton의 여러 병렬 프로세스). Singleton은 EJB가 아니지만 EJB가 사용하는 EJB 서비스가 있습니다. 주어진 엔티티 (간단한 DTO)에 대한 실행 컨텍스트를 나타내는 클래스가 있습니다. 실행 컨텍스트는 필요한 EJB에 대한 종속성을 유지하며 MDB 상호 작용 단계에서 생성되며 통지와 함께 새 메시지 (기본적으로 MDB에는 해당 EJB 및 EM의 주입 주석이 있으며 주입 된 인스턴스를 전달하는 새 실행 컨텍스트가 생성 됨)와 함께 Singleton 서비스로 전달됩니다.

문제는 엔티티 처리가 시작되었지만 EntityManager가 검색 요청에 대해 null을 반환하기 시작한 시점에서 엔티티 관리자가 업데이트 된 지 얼마되지 않았습니다.

아키텍처가 좋지 않은 것처럼 보입니다. 나는 EM의 행동이 MDB와 Singleton 사이의 상호 작용이 끝나고 얼마 후에 Persistence Context가 사라 졌다는 신호라고 생각한다. 싱글 톤의 수명은 시스템에있는 관리 빈의 수명보다 훨씬 깁니다. 따라서 EJB 인스턴스 (및 EM 인스턴스)를 이러한 구성 요소에 주입하는 것은 전혀 해결책이 아닌 것 같습니다 (주입 된 EJB 인스턴스에 대한 참조를 MDB에서 Singleton으로 전달하는 것은 아마도 최악의 결정입니다).

아마도 EJB와 EM은 필요할 때마다 JNDI를 사용하여 Singleton에서 조회해야합니다. 이 경우 각 호출에 대해 EJB를 잠글 수 있습니까?

MDB가 엔티티로만 메시지를 등록한 경우 시스템을 어떤 방법으로 설계 할 것입니까? 그리고 엔티티의 처리가 후자로 시작될 수 있습니다. 일부 EJB 서비스 (로컬 인터페이스)를 사용해야합니다. 엔티티 관리자도 있습니다.

답변

0

싱글 톤이 사용하는 엔티티 관리자가 트랜잭션 범위 인 경우 Singleton의 수명은 중요하지 않습니다. 어떤면에서, 스테이트리스 세션 빈은 한번 생성되면 무한한 수명을 갖습니다 (그들의 범위는 본질적으로 'none'이지만 그 인스턴스는 풀링되고 계속 재사용됩니다).

싱글 톤의 메소드가 요청을 처리 할 때마다 엔티티 관리자 인스턴스가 이러한 요청을 통해 동일하게 보이더라도 새로운 트랜잭션이 시작되고 새 지속성 컨텍스트가 피기 백됩니다. 이는 정상적인 동작이며 '갑자기'null을 반환하지 않아야합니다.

싱글 톤이 적절한 잠금을 사용하고 있는지 확인하는 것이 좋습니다. 엔티티 관리자가 동시에 액세스되는 경우 이는 정의되지 않은 동작의 원인 일 수 있습니다.

+0

EM은 동시에 사용되지만 단일 엔터티는 시퀀스의 전용 스레드에서 처리됩니다 (스레드는 Singleton의 큐에서 가져온 각 엔터티에 대해 만들어집니다). 대기열에는 엔티티의 ID가 들어 있습니다. 스레드가 시작 되 자마자 첨부 된 EM을 사용하여 ID로 엔티티를 조회합니다. 처리 순서 엔티티의 첫 번째 단계에서 엔티티는 null이 아니며 멤버 (참조)를 적절히 초기화했습니다. 추가 단계에서 ID로 EM에 의해 엔티티가 반환되지 않거나 엔티티의 멤버가 올바르게 채워지지 않을 수 있습니다. 관계 컬렉션이 null 일 수 있습니다. – aillusions

+0

> EM이 동시에 사용됩니다. 실제로 해당되는 경우 기본적으로 모든 베팅이 해제됩니다. 단일 스레드에서 단일 엔티티를 처리하는 것이 중요하지 않습니다.공유 EM을 사용하면 동작이 정의되지 않으며 정의되지 않은 동작의 개념은 복잡한 구현 세부 정보를 모르는 상태에서 논리로 설명 할 수 없다는 것입니다 (어쨌든 의존하지 말아야 함). 따라서 솔루션은 상당히 단순해야합니다. 엔티티 관리자를 공유하지 마십시오. –

+0

감사합니다. 나는 당신이 옳다고 생각합니다. EM에 대한 일련의 요청은 그들 사이에 잠깐 멈추어 서 동일한 엔티티를 찾는 다른 결과를 제공합니다. 다른 스레드에 대해 별도의 EM 인스턴스를 만드는 방법은 무엇입니까? EntityManagerFactory 사용하기? – aillusions