用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>
分享到:
相关推荐
里边是安装后的,包括exe文件,可以尝试使用,美国biapac公司发布的好像是,用来分析脑电心电信号没问题。
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,net,socket,通讯开发,jms /* * @(#)Message.java 1.60 02/04/09 * * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. * * SUN ...
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/queue/adaption_...
19 Acknowledge Frames _______________________________________________________42 20 Radio control state machine __________________________________________________44 21 MAC Security Operations ...
Acknowledge4.2安装包,包括AckSetup.exe直接运行安装即可。
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
c) Client_ACKNOWLEDGE方式需要显示调用方法ACKNOWLEDGE方法来显式的确认消息 d) Client_ACKNOWLEDGE方式可以确认所有的消息 参考答案 20) 关于消息Bean事务描述正确的是 c a) MDB支持RequiresNew事务方式 ...
Acknowledge TT BRK
* JMS Client:是指使用JMS服务的应用程序。 1.3 JMS 编程模型 JMS编程模型主要包括以下几个部分: * ConnectionFactory:是指创建连接工厂的接口。 * Connection:是指与消息代理服务器的连接接口。 * Session:...
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 是一个简单的 bash 脚本,它可以轻松生成一个 rtf,其中包含您在 iOS 或 OSX 项目中使用的库、框架和其他代码的所有确认。 它与和配合得很好。 Acknowledge 依赖于 。 设置 克隆 克隆这个 repo,最好是...
。。。
。。。
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...
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. ___...
Shutting down client.\n"); ex.printStackTrace(); exit(1); } private: void cleanup() { if (connection != NULL) { try { connection->close(); } catch (cms::CMSException& ex) { ex....
* Description : Master Send Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Ack(void) { ...