Java 使用 Spring 的 CachingConnectionFactory 时关闭会话
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18863057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Closing Session when using Spring's CachingConnectionFactory
提问by Gaurav
The java doc hererelated to Spring CachingConnectionFactory has comment :
这里与 Spring CachingConnectionFactory 相关的 java 文档有评论:
NOTE: This ConnectionFactory requires explicit closing of all Sessions obtained from its shared Connection. This is the usual recommendation for native JMS access code anyway. However, with this ConnectionFactory, its use is mandatory in order to actually allow for Session reuse.
注意:此 ConnectionFactory 需要显式关闭从其共享连接获得的所有会话。无论如何,这是对本机 JMS 访问代码的通常建议。但是,对于此 ConnectionFactory,它的使用是强制性的,以便实际允许 Session 重用。
I am not clear how to handle this with the below given configuration in my application.
我不清楚如何在我的应用程序中使用以下给定的配置来处理这个问题。
<bean id="springApp" class="com.codereq.springcore.jms.SpringJMSListenerApp" />
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="destination" ref="destination"/>
<property name="messageListener" ref="messageListener"/>
<property name="sessionTransacted" value="true"/>
<property name="concurrentConsumers" value="5" />
<property name="maxConcurrentConsumers" value="15" />
</bean>
<bean id="messageListener" class="com.codereq.springcore.jms.MessageListenerApp" />
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"
p:targetConnectionFactory-ref="emsConnectionFactory"
p:sessionCacheSize="100"
p:cacheConsumers="true" />
<bean id="emsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="GenericConnectionFactory"/>
<property name="jndiTemplate" ref="jndiTemplate"/>
</bean>
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</prop>
<prop key="java.naming.provider.url">tibjmsnaming://localhost:7222</prop>
<prop key="java.naming.security.principal">admin</prop>
<prop key="java.naming.security.credentials">admin</prop>
</props>
</property>
</bean>
<bean id="destination" class="com.tibco.tibjms.TibjmsQueue">
<constructor-arg value="com.sample.queue" />
</bean>
The listener class is this :
侦听器类是这样的:
public class MessageListenerApp implements MessageListener {
private static int c = 0;
@Override
public void onMessage(Message arg0) {
try {
System.out.println("Received Message..."+arg0.getStringProperty("MessageNum")+". Waiting to finish..");
Thread.sleep(2000);
System.out.println("Finished processing.."+arg0.getStringProperty("MessageNum")+".."+(c++));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
How do I follow recommendation that Sessions obtained from shared connection should be closed explicitly ?
我如何遵循从共享连接获得的会话应该明确关闭的建议?
Came across SessionAwareMessageListener interface which provides onMessage method which gives handle to Session. So to properly implement session closing, should this interface be implemented ?
遇到了 SessionAwareMessageListener 接口,该接口提供了为 Session 提供句柄的 onMessage 方法。那么要正确实现会话关闭,是否应该实现这个接口?
回答by Gary Russell
It is generally not a good idea to use a caching connection factory with a listener container, especially when using maxConcurrentConsumers
> concurrentConsumers
- you can end up with cached consumers in the cache, which get messages where there is no listener, and such messages can get "stuck".
将缓存连接工厂与侦听器容器一起使用通常不是一个好主意,尤其是在使用maxConcurrentConsumers
> 时concurrentConsumers
- 您最终可能会在缓存中缓存消费者,它们在没有侦听器的地方获取消息,而此类消息可能会“卡住” ”。
So, don't use a CCF
in this case, it's really intended for use on the producer side.
因此,CCF
在这种情况下不要使用 a ,它实际上是用于生产者方面的。
Since the container manages concurrency, the sessions/consumers are long-lived and don't need to be cached.
由于容器管理并发,会话/消费者是长期存在的,不需要缓存。
回答by Limestone
Application is not required to close the Session when using DefaultMessageListenerContainer, it creates the required sessions and closes them during shutdown.
使用DefaultMessageListenerContainer 时,应用程序不需要关闭会话,它会创建所需的会话并在关闭期间关闭它们。
Per my understanding the note you mentioned applies when Session is created by application using CachingConnectionFactory reference about which spring will have no clue.
根据我的理解,当应用程序使用 CachingConnectionFactory 参考创建 Session 时,您提到的注释适用于哪个弹簧不知道。