0

标题可能令人困惑,但这是我想要完成的。我想从 1 个 ejb 向另一个 ejb 发送 jms 消息,第 2 个 ejb 有一个消息侦听器,现在可以正常工作。但我希望第一个 ejb 创建一个临时目标队列,第二个 ejb 将在其中响应 - 这也可以正常工作。

我的问题出在第二个 ejb 中,它正在调用第 3 方 Web 服务,该服务有时会在很长一段时间后响应,并且临时队列应该在那个时候到期。但问题是它不符合java.net:http://java.net/projects/mq/lists/users/archive/2011-07/message/22

The message hasn't been delivered to a client and it expires -- in this case, the message is deleted when TTL is up.
The message is delivered to the JMS client (it's in-flight). Once this happens, since control is handed to the jms client, the broker cannot expire the message.
Finally, the jms client will check TTL just before it gives the message to the user application. If it's expired, we will not give it to the application and it will send a control message back to the broker indicating that the message was expired and not delivered.

所以,收到了,但还没有回复。然后在它写入临时队列的时候它应该已经过期但由于某种原因我仍然能够写入队列并且我的 imq 日志中有 ff:

1 messages not expired from destination jmsXXXQueue [Queue] because they have been delivered to client at time of the last expiration reaping

是否有另一种实现可以检测临时队列是否已过期?以便我可以执行另一组操作?因为我现在的问题是 ejb2 响应较晚,并且 ejb1 没有更多的 jms 阅读器,因为它已经消失了。

4

1 回答 1

0

它现在可以工作了,我的解决方案是将第一个无状态 bean(第一个 jms 消息的来源)包装在一个 bean 托管事务中。请参见下面的代码:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
@LocalBean
public class MyBean {
    public void startProcess() {
        Destination replyQueue = send(jmsUtil, actionDTO);
        responseDTO = readReply(jmsUtil, replyQueue, actionDTO);
        jmsUtil.dispose();
    }

    public Destination send(JmsSessionUtil jmsUtil, SalesOrderActionDTO soDTO) {
        try {
            utx.begin();
            jmsUtil.send(soDTO, null, 0L, 1,
                    Long.parseLong(configBean.getProperty("jms.payrequest.timetolive")), true);
            utx.commit();
            return jmsUtil.getReplyQueue();
        } catch (Exception e) {
            try {
                utx.rollback();
            } catch (Exception e1) {

            }
        }
        return null;
    }

    public ResponseDTO readReply(JmsSessionUtil jmsUtil, Destination replyQueue,
                SalesOrderActionDTO actionDTO) {
            ResponseDTO responseDTO = null;
        try {
            utx.begin();

            responseDTO = (ResponseDTO) jmsUtil.read(replyQueue);

            if (responseDTO != null) {
                //do some action
            } else { // timeout
                ((TemporaryQueue) replyQueue).delete();
                jmsUtil.dispose();
            }
            utx.commit();
            return responseDTO;
        } catch (Exception e) {
            try {
                utx.rollback();
            } catch (Exception e1) {
            }
        }
        return responseDTO;
    }
}
于 2013-01-07T03:13:24.073 回答