Spring JMS - 通过将消息发送回同一队列而不是回滚事务来重新传递

vor*_*lex 5 queue spring transactions rollback spring-jms

这是我在这里发表的第一篇文章,因此如果我不遵守格式规则或其他一般规则,我提前道歉。

我有一个基于 Spring JMS 的客户端应用程序,它使用多个使用者从队列中读取数据。我的限制是:在失败和消息重复检测的情况下保证重新传递。

弹簧配置

<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver" />


    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <constructor-arg ref="MyConnectionFactory" />
        <property name="destinationResolver" ref="jndiDestinationResolver" />
        <property name="receiveTimeout" value="100" />
    </bean>


    <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
            <property name="destinationResolver" ref="jndiDestinationResolver" />
            <property name="connectionFactory" ref="MyConnectionFactory" />
            <property name="destinationName" value="my_Queue" />
            <property name="messageListener" ref="MyListener" />
            <property name="maxConcurrentConsumers" value="10"/>
            <property name="sessionTransacted" value="true"/>
    </bean>
Run Code Online (Sandbox Code Playgroud)

我的监听器代码类似于:

    protected void processTextMessage(TextMessage textMessage) {
        尝试 {
            // 处理消息
        } catch(异常e){
            尝试 {
                sendTextMessage("my_Queue",correlationID, textMessage.getText());
            } catch (JMSException e1) {
                log.error("将消息写回队列时出错!");
                抛出 JmsUtils.convertJmsAccessException(e1);

            }
        }
    }


    protected void sendTextMessage(字符串队列名称,最终字节[]相关ID,字符串消息){
        jmsTemplate.convertAndSend(queueName, message, new MessagePostProcessor() {
            公共消息 postProcessMessage(消息消息)抛出 JMSException {
                message.setJMSCorrelationIDAsBytes(correlationID);
                返回消息;
            }
        });
    }

我使用 ActiveMQ 进行了一些本地故障测试,重新发送没问题(我注意到重新发送标志为 false)。我还尝试在处理过程中粗暴地停止应用程序服务器,并且能够在该时刻队列中检查到包含 1 条消息且 redelivered=true 的消息。

这是实现我的目标的正确方法吗?

我希望这对于我将使用的 JMS 提供程序是透明的(在生产环境中使用 Websphere MQ)。目前,我想避免通过抛出异常来回滚事务:我希望重新安排我的失败消息,就像队列中的新消息一样。对于重复检测,我认为插入业务存在检查就足够了。

预先致谢并致以诚挚的问候

Gar*_*ell 2

是的,这是正确的做法。