Transactions 具有异常处理的JMS事务

Transactions 具有异常处理的JMS事务,transactions,jms,Transactions,Jms,我正在设计JMS应用程序,它从队列接收消息并更新数据库中的列。我使用tomcat和消息侦听器来侦听消息(并没有MDB和Spring MDP)。我想要最好的、健壮的设计,以防异常处理和事务丢失消息 我应该使用jms会话事务模式,也应该使用jdbc事务模式。 或者只需要jdbc事务就足够了(没有jms会话提交或回滚),因为这是一个数据库表更新 谢谢一个JDBC事务是不够的:如果您已经阅读了一条消息,并且数据库操作失败,并且关闭了tomcat,那么消息就会丢失 如果每条消息都触发数据库中的插入/更新

我正在设计JMS应用程序,它从队列接收消息并更新数据库中的列。我使用tomcat和消息侦听器来侦听消息(并没有MDB和Spring MDP)。我想要最好的、健壮的设计,以防异常处理和事务丢失消息

我应该使用jms会话事务模式,也应该使用jdbc事务模式。 或者只需要jdbc事务就足够了(没有jms会话提交或回滚),因为这是一个数据库表更新


谢谢

一个JDBC事务是不够的:如果您已经阅读了一条消息,并且数据库操作失败,并且关闭了
tomcat
,那么消息就会丢失


如果每条消息都触发数据库中的插入/更新,则可以使用
CLIENT\u-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();

如果多条消息导致一个数据库操作(您必须收集一些消息,然后才能更新数据库),则需要此模式。

JDBC事务是不够的:如果您读取了一条消息,数据库操作失败,并且关闭了
tomcat
,则消息将丢失


如果每条消息都触发数据库中的插入/更新,则可以使用
CLIENT\u-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();
如果多条消息导致一个数据库操作,则需要此模式(必须先收集一些消息,然后才能更新数据库)