TemporaryQueue를 통해 다른 모듈의 MDB와 메시지를 동기식으로 교환해야하는 EJB 모듈이 있습니다. EJB 컨테이너 (제 경우에는 Glassfish 4.0 임)는 트랜잭션 환경을 가정하고 BEAN 관리 트랜잭션을 사용해야하며 UserTransaction 객체를 사용하여 트랜잭션의 시작과 끝을 표시해야합니다.트랜잭션 환경의 JMS 요청/응답 패턴
내 코드의 외형이 같다 :
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class CommunicationJMSUtils {
@Resource
private UserTransaction ut;
@Inject
private JMSContext context;
@Resource(lookup = "jms/DestinationQueue")
private Queue destination;
private static final long JMS_COMMUNICATION_TIMEOUT = 5000;
public Map<String, String> getClientordersData(String id) throws JMSException {
try {
MapMessage mm = context.createMapMessage();
ut.begin();
TemporaryQueue replyQueue = context.createTemporaryQueue();
mm.setJMSReplyTo(replyQueue);
mm.setStringProperty(<...>);
<...>
mm.setString(<...>);
<...>
context.createProducer().send(destination, mm);
ut.commit();
ut.begin();
ObjectMessage om = (ObjectMessage) context.createConsumer(replyQueue).receive(JMS_COMMUNICATION_TIMEOUT);
ut.commit();
if (om != null) {
return om.getBody(Map.class);
} else {
throw new JMSException("Failed to receive reply within " + JMS_COMMUNICATION_TIMEOUT);
}
} catch (NotSupportedException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException | SystemException ex) {
<...>
}
}
}
첫 번째 문제는 때때로이 코드 (수신 부분)이다 제외
MQJMSRA_DS4001: _checkDestination:Temporary Destination not owned by parent connectionId=1760697170479431168
분명히 TemporaryQueue 생성되지만 실패 같은 JMSContext를 사용합니다.
두 번째 문제는이 코드의 "취약성"입니다. 첫 번째 트랜잭션 내에 context.createMapMessage()를 두거나 첫 번째 트랜잭션에서 TemporaryQueue를 이동하면이 스 니펫은 확실히 실패합니다.
유감스럽게도 JMS 자습서/문서는 실제로 해당 사용 사례를 다루지 않습니다. Java EE에서 JMS 2.0을 사용하여 JMS 요청/응답 패턴을 구현하는 올바른 방법은 무엇입니까?
비동기 메시징은 모듈 간 특정 인터페이스가 없도록 선택되었습니다. 나는 리모트 인터페이스가 같은 방법으로 어느 정도 사용될 수 있다는 것을 알고있다. 트랜잭션 간의 리소스 공유는 실제 문제이며 (일반적으로이 질문의 이유입니다). 참고 자료에서는 JMS를 사용하여 동기식 교환 패턴을 찾을 수 있지만 명확한 구현 예는 찾을 수 없습니다. 답장을 보내 주셔서 감사합니다. 건축 설계를 재고해야한다고 생각합니다. – vsviridov
빈 관리 트랜잭션을 사용해야하는 이유는 분명하지 않습니다.비즈니스 메소드에서 다양한 트랜잭션에 대한 세분화 된 제어가 필요한 경우가 아니라면 컨테이너가 트랜잭션을 관리하도록하는 것이 좋습니다. –
@IanEvans 귀하의 의견은 OP를위한 것 같습니다. 어쨌든 내 대답은 BMT의 일반적인 측면만을 다룹니다. 제안/결론은 또 다른 설계입니다 (CMT는이 경우 잘되어야합니다). – Beryllium