`
louisling
  • 浏览: 144410 次
  • 性别: Icon_minigender_1
  • 来自: ZhuHai
社区版块
存档分类
最新评论

Spring JMS CLIENT_ACKNOWLEDGE

阅读更多
用Spring 的 JmsTemplate 来接收消息时, 按照其文档:
/*
Default settings for JMS Sessions are "not transacted" and "auto-acknowledge". As defined by the J2EE specification, the transaction and acknowledgement parameters are ignored when a JMS Session is created inside an active transaction, no matter if a JTA transaction or a Spring-managed transaction. To configure them for native JMS usage, specify appropriate values for the "sessionTransacted" and "sessionAcknowledgeMode" bean properties. 
*/


按照JMS 规范, 如果是在事务内部接收消息, 会忽略sessionAcknowledgeMode 选项, Session.sessionAcknowledgeMode 总是 auto-acknowledge. 如果在事务外部调用,默认是 auto-acknowledge的, 如果需要定义为其他 acknowledge mode, 设置sessionTransacted 和sessionAcknowledgeMode属性. 但是, 当我设置sessionTransacted为false, sessionAcknowledgeMode为 client acknowledge 时, 如果调用消息的 acknowledge 方法, 会抛出异常, 因为每次接收完了消息, JmsTemplate 会将 Session 和 Connection 都关闭. 而且消息也是auto-acknowledge的.

查看JmsTemplate 的原代码,发现:
最终接收消息的代码会进入这个方法:
protected Message doReceive(Session session, MessageConsumer consumer)

这是个 protected 方法, subclass 可以 override 它.
于是跟踪进去看看里面的代码发现:
if (session.getTransacted()) {
    // Commit necessary - but avoid commit call within a JTA transaction.
    if (isSessionLocallyTransacted(session)) {
        // Transacted session created by this template -> commit.
        JmsUtils.commitIfNecessary(session);
    }
}
else if (isClientAcknowledge(session)) {
    // Manually acknowledge message, if any.
    if (message != null) {
        message.acknowledge();
    }
}


注意到这句: else if (isClientAcknowledge(session)) {

这就是在事务外部接收消息后的处理, 如果我们设置了Session 为 client acknowledge 模式, JmsTemplate 会在这里acknowledge 接收到的消息的.

刚好可以 override 这部分代码, 嵌入我们自己的处理, 让我们自己来决定是否 acknowledge 接收到的消息.

解决方法:
1)
public interface MessageHandler {
    
    /** 
     * Process the message, if process finish successfully, return true, otherwise false
     * return true if process successfully
     */
    boolean processMessage(Message message);
}



2) Extend JmsTemplate, override JmsTemplate's method: protected Message doReceive(Session session, MessageConsumer consumer).

public class MyJmsTemplate extends JmsTemplate {
...
} else if (isClientAcknowledge(session)) {
    // Manually acknowledge message if MessageHandler is not null and process message successfully
    if (message != null) {
        if (messageHandler == null || (messageHandler != null && messageHandler.processMessage(message)))
            message.acknowledge();
    }
}


3) Sample MessageHandler
public class SampleMessageHandler implements MessageHandler {

    @Override
    public boolean processMessage(Message message) {
        try {
            int flag = message.getIntProperty("flag");
            return (flag < 2);
        } catch (JMSException e) {
            e.printStackTrace();
            return false;
        }
    }

}


4) 测试时, 设置一下sssionTransacted 和 sssionAcknowledgeMode.
<bean id="myJmsTemplate" class="com.zero.demo.jms.MyJmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>        
    <property name="defaultDestination" ref="authReplyDestination"/>
    
    <property name="sessionTransacted" value="false"/>
    <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>        
    <property name="messageHandler">
        <bean class="com.zero.demo.jms.SampleMessageHandler"/>
    </property>
</bean>

1
0
分享到:
评论
2 楼 makemyownlife 2011-09-21  
您好 ,和您讨论一个问题 ,在spring 和jms结合里 我发现
<property name="sessionTransacted" value="false"/>
<property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>

以上配置中无论如何,spring都会自己默认 确认。请问 是这样吗?
1 楼 matt.u 2009-04-09  
估计Spring组织通常都推荐大家使用异步处理的方式,因为只要在使用接收处理函数中抛出异常,MessageListenerContainer就不会调用message.acknowledge(),可参见AbstractMessageListenerContainer#commitIfNecessary。

如果必须使用Receive来同步处理消息,也许也推荐在同一Session事务中处理比较合适。

以上都是看了代码后,个人得出的结论。
不代表官方观点。

相关推荐

    spring,weblogic配置jms

    - 考虑到事务管理,根据业务需求选择合适的事务配置,例如`CLIENT_ACKNOWLEDGE`或`AUTO_ACKNOWLEDGE`等确认模式。 - 如果遇到性能问题,可以考虑调整WebLogic Server的JMS配置,如缓存大小、并发消费者数量等。 ...

    spring-boot-activemq-demo

    在`pom.xml`文件中,我们需要添加`spring-boot-starter-jms`和`activemq-client`依赖,以便利用Spring JMS API和ActiveMQ客户端库。 ```xml &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-...

    ActiveMQ使用教程

    - CLIENT_ACKNOWLEDGE:客户端通过消息的acknowledge方法手动确认。 - DUPS_ACKNOWLEDGE:延迟确认,可能造成消息重复。 2. **持久性(Durability)** 消息可以设置为持久性(PERSISTENT)或非持久性(NON_...

    spring整合activemq的maven工程

    &lt;jms:listener-container connection-factory="connectionFactory" acknowledge="auto"&gt; &lt;jms:listener destination="myQueue" ref="messageListener" /&gt; &lt;/jms:listener-container&gt; ``` 最后,在Java代码中,...

    SpringActiveMQ.rar

    9. **消息确认**:ActiveMQ支持两种确认模式:自动确认(Auto Acknowledge)和客户端确认(Client Acknowledge)。客户端确认允许应用在适当的时候手动确认消息已被处理,以防止消息丢失。 10. **故障转移和集群**...

    activemq工具类

    关于消息的确认,ActiveMQ支持两种确认模式:自动确认(auto-acknowledge)和手动确认(client-acknowledge)。默认情况下,ActiveMQ使用自动确认模式,即消息一旦被消费就会自动确认。如果你希望在处理完消息后再...

    activemq + spring

    总结来说,"activemq + spring"的主题涵盖了使用Java原生API连接ActiveMQ以及通过Spring框架实现更高级别的整合,包括利用Spring的JMS支持简化消息发送和接收。这些知识对于构建基于消息驱动的分布式系统,实现解耦...

    [课堂课件讲解]Java微服务实践-Spring Boot 消息.pptx

    JMS消息确认(Acknowledgment)是指客户端确认收到JMS消息的机制,可以使用acknowledge方法来确认消息的收到。 高级消息队列协议(AMQP) 高级消息队列协议(AMQP)是一种针对面向消息中间件的开放标准应用层协议...

    spring mq集成 web工程发送和接收消息例子

    &lt;jms:listener-container connection-factory="connectionFactory" acknowledge="auto"&gt; &lt;jms:listener destination="myQueue" ref="messageListener" /&gt; &lt;/jms:listener-container&gt; ``` 在这里,我们创建了一...

    springboot整合activeMq的使用,队列,主题,消息手动确认,重发机制

    在`pom.xml`文件中,你需要引入Spring Boot的`spring-boot-starter-jms`和ActiveMQ的客户端库: ```xml &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-starter-jms &lt;groupId&gt;org.apache....

    active-demo:ActiveMQ + Spring 整合

    &lt;jms:listener-container connection-factory="connectionFactory" acknowledge="auto"&gt; &lt;jms:listener destination="myQueue" ref="messageListener" method="onMessage"/&gt; &lt;/jms:listener-container&gt; ``` ...

    消息事件说明文档

    - **集成Spring框架**:能够无缝地集成到使用Spring的应用程序中,并支持Spring 2.0的新特性。 - **兼容主流服务器**:已经过Geronimo、JBoss、GlassFish和WebLogic等主流J2EE服务器的测试,并可通过JCA 1.5 ...

    java mes发消息实例

    此外,对于大型项目,通常会使用Spring框架的JMS支持来简化消息队列的集成和管理。 这个实例只是基础,要完全掌握Java MES发消息,还需要深入学习和实践,包括理解不同的消息模型(点对点、发布/订阅),优化性能,...

Global site tag (gtag.js) - Google Analytics