【问题标题】:How to properly close a JMS connection?如何正确关闭 JMS 连接?
【发布时间】:2017-06-07 22:22:08
【问题描述】:

我正在尝试使用 Spring 的 SingleConnectionFactory,其中有 2 个连接工厂,一次应该只有一个能够连接。

<bean id="connectionFactory1" class="org.springframework.jms.connection.SingleConnectionFactory102">
    <property name="targetConnectionFactory">
        <bean class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
            <property name="username" value="LOGIN" />
            <property name="password" value="PASS" />
            <property name="targetConnectionFactory">
                <bean class="com.tibco.tibjms.TibjmsQueueConnectionFactory">
                    <constructor-arg value="URL" />
                    <constructor-arg value="CLIENT_ID" />
                </bean>
            </property>
        </bean>
    </property>
    <property name="reconnectOnException" value="true" />
</bean>

<bean id="connectionFactory2" class="org.springframework.jms.connection.SingleConnectionFactory102">
    <property name="targetConnectionFactory">
        <bean class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
            <property name="username" value="LOGIN" />
            <property name="password" value="PASS" />
            <property name="targetConnectionFactory">
                <bean class="com.tibco.tibjms.TibjmsQueueConnectionFactory">
                    <constructor-arg value="URL" />
                    <constructor-arg value="CLIENT_ID" />
                </bean>
            </property>
        </bean>
    </property>
    <property name="reconnectOnException" value="true" />
</bean>

通过在两个工厂(CLIENT_ID)中使用相同的客户端 ID,我确保当我从一个工厂创建连接时,我无法从另一个工厂创建另一个连接(抛出 InvalidClientIDException,所以这是预期的)。但问题是,当我关闭从第一个工厂获得的连接并尝试从第二个工厂获得连接时,我仍然遇到异常。

使用以下 Java 代码:

Connection connection1 = connectionFactory1.createConnection();
connection1.close();

Connection connection2 = connectionFactory2.createConnection();

关闭第一个连接的正确方法是什么,以便我可以使用第二个工厂创建连接?

另外,请注意我在这里没有使用队列。我必须在没有队列的情况下实现这一点。

【问题讨论】:

  • 检测到你打开第一个连接抛出错误的逻辑是什么?
  • factory.resetConnection()
  • @MinhKieu,我在两个工厂中使用相同的 CLIENT_ID,因此尝试从不同的工厂创建另一个连接会导致异常。

标签: java jms spring-jms


【解决方案1】:

使用factory.resetConnection() 实际关闭单个连接。

【讨论】:

  • 你在哪里有那个方法resetConnection()?我查了一下,SingleConnectionFactory102中没有这个方法。
  • 您使用的是什么版本的 Spring?该工厂在 3.2 之后不存在。至少在 3.2 中,resetConnection()super class SingleConnectionFactory 上。如果您的版本中没有resetConnection(),请尝试destroy()
  • 我的spring版本是2.5。我可以试试以后的版本。
  • resetConnection() 存在于 2.5 see the javadocs
  • 对,它在 2.5 版本中可用。我检查了,它解决了这个问题。谢谢!
【解决方案2】:

我不会推荐接受的答案。让我来谈谈这个问题以及这个问题的其他答案提出的几点。

更好的方法类似于这个示例(JavaEE6 JMS 样式),它从无状态 EJB 中将 ObjectMessage 发送到队列:

@Stateless
public class SendEventsBean {

  private static final Logger log = Logger.getLogger(SendEventsBean.class);

  @Resource(mappedName = "jms/MyConnectionFactory")
  private ConnectionFactory jmsConnectionFactory;

  @Resource(mappedName = "jms/myApp/MyQueue"
  private Queue queue;

  public void sendEvent() {
    Connection jmsConnection = null;
    try {
        connection = jmsConnectionFactory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = session.createProducer(queue);
        MyObj obj = new MyObj(1, "Foo");
        ObjectMessage myObjMsg = session.createObjectMessage(obj);
        producer.send(myObjMsg);
    } catch (JMSException jmxEx) {
        log.error("Couldn't send JMS message: ", jmsEx);
    }finally{
        if (jmsConnection != null) {
            try {
                jmsConnection.close();
            }catch(JMSException ex) {
               log.warn("Couldn't close JMSConnection: ", ex);
            }
        }
    }
  }

}

【讨论】:

  • 但是,我需要它而不涉及队列。为此,我请求在我的公司基础架构中创建新的 EMS 队列是不可行的。
猜你喜欢
  • 1970-01-01
  • 2018-02-14
  • 2023-03-22
  • 1970-01-01
  • 2014-08-22
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多