【问题标题】:Why is Session.CLIENT_ACKNOWLEDGED not honoured?为什么 Session.CLIENT_ACKNOWLEDGED 不被尊重?
【发布时间】:2013-10-17 02:33:20
【问题描述】:

我尝试使用 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

【问题讨论】:

  • 您是否正在查找远程连接工厂以获取连接?如果是这样,请检查出厂设置。不同的供应商为各种连接和会话设置提供默认值,
  • @raffian 编辑为您提供更多信息

标签: java session jakarta-ee glassfish jms


【解决方案1】:

测试有疑问?还是不行?

因此,为了调查这一点,我创建了一个单元测试,在其中创建了一个会话,然后检查 getTransacted() 和 getAcknowledgeMode() 的值。

这个测试显然证实了我上面问的问题,也就是说在配置了Session.AUTO_ACKNOWLEDGE的JMS会话中输入Session.CLIENT_ACKNOWLEDGEresults ...什么?

是的,我也完全惊呆了。

这里有龙

所以我做了你们在玩 Glassfish 时应该做的事情。我安装了最新版本的Jadclipse 并重新开始测试,尽我所能调试。

创建ConnectionFactory 似乎没问题

创建Connection 似乎也可以

但是创建 Session 是从那段代码开始的(从我在 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 .. mmh,看来实际上,不,我不能(此外,请注意常见问题解答是哪个高质量的由oracle提供...)。

所以剩下的唯一解决方案是......,是的,对于疼痛,在会话创建之前插入一点静态

static {
    /*
     * Want to know why ? http://stackoverflow.com/q/19277018/15619 this is why
     */
    System.setProperty("imq.jmsra.fixCR6760301", Boolean.FALSE.toString());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    相关资源
    最近更新 更多