我尝试使用Session.CLIENT_ACKNOWLEDGE
作为确认模式启动无事务JMS会话。
不幸的是,当我开始会话时,确认模式始终为Session.AUTO_ACKNOWLEDGE
。为什么?
我正在从远程glassfish客户端连接到glassfish服务器(使用标准的嵌入式OpenMQ代理)。会话初始化代码是
boolean transacted = false;
int acknowledgeMode = Session.CLIENT_ACKNOWLEDGE;
session = getConnection().createSession(transacted, acknowledgeMode);
if(transacted!=session.getTransacted())
throw new UnsupportedOperationException("seems like the broker doesn't want us to use untransacted connection");
if(acknowledgeMode!=session.getAcknowledgeMode())
throw new UnsupportedOperationException("seems like the broker doesn't want us to use Session.CLIENT_ACKNOWLEDGE");
[编辑1]
Session是从Connection / ConnectionFactory对中获取的,其中使用JNDI查找connectionFactory:
connectionFactory = (ConnectionFactory) getContext().lookup(JMSConstants.CONNECTION_FACTORY_NAME);
所以我确实可以使用远程连接工厂的默认设置as @raffian suggested
答案 0 :(得分:0)
因此,为了调查这一点,我创建了一个单元测试,在其中我创建了一个会话,然后检查getTransacted()
和getAcknowledgeMode()
的值。
这个测试显然证实了我问上方的问题,那就是说在Session.CLIENT_ACKNOWLEDGE
配置的JMS会话中输入Session.AUTO_ACKNOWLEDGE
结果......什么?
是的,我也完全惊呆了。
所以我做了你在Glassfish玩的时候应该做的事情。我安装了最新版本的Jadclipse并重新开始我的测试,尽我所能调试。
创建ConnectionFactory
似乎没问题
创建Connection
似乎也没问题
但是创建会话就是从那个代码开始的(从我在com.sun.messaging.jms.ra.ConnectionAdapter
的Jadclipse会话中再现 - 看看ConnectionAdapter#createSession
)。
if (ResourceAdapter._isFixCR6760301())
{
localXASessionImpl = (XASessionImpl)this.xac.createSession(overrideTransacted(paramBoolean), overrideAcknowledgeMode(paramInt), (this.inACC) ? null : this.mc);
}
else {
localXASessionImpl = (XASessionImpl)this.xac.createSession((this.mc.xaTransactionStarted()) ? true : paramBoolean, paramInt, (this.inACC) ? null : this.mc);
}
显然,我的确认模式是通过调用ConnectionAdapter#overrideAcknowledgeMode
的优雅来重写的。希望grepCode中的代码具有这个非常有用的评论,真正让我的一天
// EJB spec section 13.3.5 "Use of JMS APIs in Transactions" says
// "The Bean Provider should not use the JMS acknowledge method either within a transaction
// or within an unspecified transaction context. Message acknowledgment in an unspecified
// transaction context is handled by the container."
//
// The same restriction applies in web container: JavaEE Spec: "EE.6.7 Java Message Service (JMS) 1.1 Requirements" says
// "In general, the behavior of a JMS provider should be the same in both the EJB container and the web container.
// The EJB specification describes restrictions on the use of JMS in an EJB container,
// as well as the interaction of JMS with transactions in an EJB container.
// Applications running in the web container should follow the same restrictions.
但是,不幸的是,我以一种奇怪的模式运行我的Glassfish客户端(不完全是在ACC中,但与它非常相似)。
那么,我该怎么办?
哦,当然,我可以看看上面提到的臭名昭着的臭虫:CR6760301 ......嗯,事实上,似乎是不,我不能(旁边,注意哪个高质量是由oracle提供的常见问题解答......)。
所以只有剩下的解决方案是...,是的,疼痛,在会话创建之前插入一点静态
static {
/*
* Want to know why ? http://stackoverflow.com/q/19277018/15619 this is why
*/
System.setProperty("imq.jmsra.fixCR6760301", Boolean.FALSE.toString());
}