我正在设计 JMS 应用程序,它从队列接收消息并更新数据库中的列。我正在使用 tomcat 和消息侦听器来侦听消息(没有 MDB 和 Spring MDP'S)。在异常处理和事务处理中,我想要尽可能好的、健壮的设计,这样消息就不会丢失。
我是否应该使用 jms 会话事务模式以及 jdbc 事务。或者只是 jdbc 事务就足够了(没有 jms 会话提交或回滚),因为这是一个数据库表更新。
谢谢
我正在设计 JMS 应用程序,它从队列接收消息并更新数据库中的列。我正在使用 tomcat 和消息侦听器来侦听消息(没有 MDB 和 Spring MDP'S)。在异常处理和事务处理中,我想要尽可能好的、健壮的设计,这样消息就不会丢失。
我是否应该使用 jms 会话事务模式以及 jdbc 事务。或者只是 jdbc 事务就足够了(没有 jms 会话提交或回滚),因为这是一个数据库表更新。
谢谢
一个 JDBC 事务是不够的:如果你读到了一条消息,而数据库操作失败并被tomcat
关闭,那么这条消息就丢失了。
如果每条消息都触发数据库中的插入/更新,您可以使用CLIENT_ACKNOWLEDGE
模式:
final boolean transacted = false;
final int ackMode = Session.CLIENT_ACKNOWLEDGE;
final QueueSession queueSession = queueConnection.createQueueSession(
transacted, ackMode);
因此,您可以阅读消息并更新数据库。如果数据库更新成功,您可以使用确认消息
message.acknowledge();
如果没有acknowledge
,则消息将被重新传递:因此,在重新启动后tomcat
,您的消息侦听器应该会再次看到该消息。您可以使用queueSession.recover()
以编程方式重新启动交付。
由于在成功的数据库更新和确认之间可能tomcat
会关闭,因此您应该确保正确处理重复的消息。
一种变体是使用事务处理会话:
final boolean transacted = true;
// 2nd parameter is ignored if the session is transacted
final QueueSession queueSession = queueConnection.createQueueSession(
transacted, -1);
在这种模式下,您可以使用单个提交确认多条消息:
queueSession.commit();
如果多条消息导致单个数据库操作,则需要此模式(您必须收集一些消息,然后才能更新数据库)。