如何正确关闭 JMS 连接
How to close JMS Connection properly
我有以下代码来轮询 JMS 中的死信队列。
Message m = mconsumer.receive(3000L);
while (m != null) {
try {
sendMessageToDB(m);
} catch (DBException ex) {
writeToDeadLetterQueueBack(m);
}
m = messageConsumer.receive(3000L);
}
现在在这个 while 循环中,如果 DBException
发生,我的连接不会关闭,如果我在 catch 块内关闭连接,下面这行将失败,因为会话现在已关闭。
m = messageConsumer.receive(3000L);
如何处理。
普遍接受的最佳做法是不 'write-back' 将消息发送到死信队列,而是 'roll it back' 使用事务处理会话。
在您的设计中,如果发生数据库中断,您将有一个不断消费和预发布消息返回死信队列的无限循环。你最好在计时器上启动这个东西(运行 每小时等).. 或者让它有某种退避逻辑来停止在错误情况下不断轮询 DLQ。
一般基于会话的一次一条消息提交和回滚处理,在 finally 块中使用适当的对象关闭例程。
Session session = connection.createSession(true, Session.TRANSACTED);
MessageConsumer consumer = session.createConsumer(session.createQueue('MY.QUEUE.DLQ');
Message m = mconsumer.receive(3000L);
while (m != null) {
try {
sendMessageToDB(m);
session.commit();
m = messageConsumer.receive(3000L);
} catch (DBException ex) {
session.rollback();
logger.error("Rolling back messageId {} due to database error {}", m.getJMSMessageId(), ex);
} finally {
if(consumer != null) {
try { consumer.close(); } catch (JMSException e) { logger.error("Error closing consumer.."); }
}
if(session != null) {
try { session.close(); } catch (JMSException e) { logger.error("Error closing session.."); }
}
if(connection != null) {
try { connection.close(); } catch (JMSException e) { logger.error("Error closing connection.."); }
}
}
}
我有以下代码来轮询 JMS 中的死信队列。
Message m = mconsumer.receive(3000L);
while (m != null) {
try {
sendMessageToDB(m);
} catch (DBException ex) {
writeToDeadLetterQueueBack(m);
}
m = messageConsumer.receive(3000L);
}
现在在这个 while 循环中,如果 DBException
发生,我的连接不会关闭,如果我在 catch 块内关闭连接,下面这行将失败,因为会话现在已关闭。
m = messageConsumer.receive(3000L);
如何处理。
普遍接受的最佳做法是不 'write-back' 将消息发送到死信队列,而是 'roll it back' 使用事务处理会话。
在您的设计中,如果发生数据库中断,您将有一个不断消费和预发布消息返回死信队列的无限循环。你最好在计时器上启动这个东西(运行 每小时等).. 或者让它有某种退避逻辑来停止在错误情况下不断轮询 DLQ。
一般基于会话的一次一条消息提交和回滚处理,在 finally 块中使用适当的对象关闭例程。
Session session = connection.createSession(true, Session.TRANSACTED);
MessageConsumer consumer = session.createConsumer(session.createQueue('MY.QUEUE.DLQ');
Message m = mconsumer.receive(3000L);
while (m != null) {
try {
sendMessageToDB(m);
session.commit();
m = messageConsumer.receive(3000L);
} catch (DBException ex) {
session.rollback();
logger.error("Rolling back messageId {} due to database error {}", m.getJMSMessageId(), ex);
} finally {
if(consumer != null) {
try { consumer.close(); } catch (JMSException e) { logger.error("Error closing consumer.."); }
}
if(session != null) {
try { session.close(); } catch (JMSException e) { logger.error("Error closing session.."); }
}
if(connection != null) {
try { connection.close(); } catch (JMSException e) { logger.error("Error closing connection.."); }
}
}
}