`
louisling
  • 浏览: 141409 次
  • 性别: 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事务中处理比较合适。

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

相关推荐

    Acknowledge软件

    里边是安装后的,包括exe文件,可以尝试使用,美国biapac公司发布的好像是,用来分析脑电心电信号没问题。

    prosys.OPC.Client.2.0.0.4

    Prosys OPC Client is a generic OPC client application supporting all main OPC information models. Browse address space, select nodes and read and write data. Access nodes that contain historical data ...

    基于Java通讯开发jms源代码 (jms通讯开发源码)

    基于Java通讯开发jms源代码 (jms通讯开发源码) java,net,socket,通讯开发,jms /* * @(#)Message.java 1.60 02/04/09 * * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. * * SUN ...

    在JBOSS 环境中配置JMS,在程序中可以通过JNDI 获取连接

    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/queue/adaption_...

    cc2420无线传感芯片说明手册

    19 Acknowledge Frames _______________________________________________________42 20 Radio control state machine __________________________________________________44 21 MAC Security Operations ...

    Acknowledge4.2软件安装包

    Acknowledge4.2安装包,包括AckSetup.exe直接运行安装即可。

    单片机与DSP中的在51上用P1口模拟I2C

     bit Check_Acknowledge(void); void Write_Byte(uchar b)reentrant; bit Write_N_Bytes(uchar *buffer,uchar n)reentrant; bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer); uchar 

    J2EE面试题

    c) Client_ACKNOWLEDGE方式需要显示调用方法ACKNOWLEDGE方法来显式的确认消息 d) Client_ACKNOWLEDGE方式可以确认所有的消息 参考答案 20) 关于消息Bean事务描述正确的是 c a) MDB支持RequiresNew事务方式 ...

    Acknowledge TT BRK

    Acknowledge TT BRK

    ActiveMQ基础知识

    * JMS Client:是指使用JMS服务的应用程序。 1.3 JMS 编程模型 JMS编程模型主要包括以下几个部分: * ConnectionFactory:是指创建连接工厂的接口。 * Connection:是指与消息代理服务器的连接接口。 * Session:...

    ActiveMQ_Demo

    import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax....

    Acknowledge::memo: Acknowledge 可以轻松地将您在 Xcode 项目中使用的库、框架和代码的确认汇总在一起

    Acknowledge 是一个简单的 bash 脚本,它可以轻松生成一个 rtf,其中包含您在 iOS 或 OSX 项目中使用的库、框架和其他代码的所有确认。 它与和配合得很好。 Acknowledge 依赖于 。 设置 克隆 克隆这个 repo,最好是...

    The Acknowledge of Computer-1.pdf

    。。。

    The Acknowledge of Computer-1.docx

    。。。

    spring开发包

    you acknowledge this fact somewhere in the documentation, research report, etc... If you like ANTLR and have developed a nice tool with the output, please mention that you developed it using ANTLR. In...

    KCF源码代码

    If you find it useful or use it in your research, please acknowledge my git repository and cite the original paper [1]. The code depends on OpenCV 2.4+ library and is build via cmake toolchain. ___...

    testActiveMQ.rar

    Shutting down client.\n"); ex.printStackTrace(); exit(1); } private: void cleanup() { if (connection != NULL) { try { connection-&gt;close(); } catch (cms::CMSException& ex) { ex....

    stm32 mpu_6050程序

    * Description : Master Send Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Ack(void) { ...

Global site tag (gtag.js) - Google Analytics