2013-09-18 3 views
6

Ява DOC here связанные с Spring CachingConnectionFactory имеет комментарий:Закрытие сессии при использовании CachingConnectionFactory Spring в

Примечание: Эта ConnectionFactory требует явного закрытия всех сеансов, полученных от его общей связи. Это обычная рекомендация для собственного кода доступа JMS в любом случае. Однако с этим ConnectionFactory его использование является обязательным, чтобы фактически разрешить повторное использование сеанса.

Я не понимаю, как с этим справиться с приведенной ниже конфигурацией в моем приложении.

<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> 

Класс слушателя это:

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(); 
    } 

} 

}

Как следовать рекомендациям, которые Сессии, полученные от общего подключения должны быть закрыты явно?

Доступен через интерфейс SessionAwareMessageListener, который предоставляет метод onMessage, который дает дескриптор сеанса. Итак, чтобы правильно реализовать закрытие сеанса, должен ли реализован этот интерфейс?

ответ

1

Это, как правило, не является хорошей идеей использовать соединение кэширования завод с слушателем контейнера, особенно при использовании maxConcurrentConsumers>concurrentConsumers - вы можете в конечном итоге с кэшированных потребителей в кэше, которые получают сообщения, где нет слушателя, и такие сообщения могут «застревать».

Итак, не используйте в этом случае CCF, он действительно предназначен для использования на стороне производителя.

Поскольку контейнер управляет параллелизмом, сеансы/потребители являются долговечными и не нуждаются в кешировании.

+0

Но все же вопрос кажется без ответа. Пусть создатель сообщения кэшируется в другом сценарии. Как обрабатывать явное закрытие сеансов, полученных из CCF? – Manu

+0

'session.close()' - комментарий javadoc просто говорит, что сеанс возвращается только в пул, когда клиент закрывает его. Если вам нужен PHYSICAL close, тогда не используйте 'CachingConnectionFactory'. Весенние клиенты (JmsTemplate, контейнер-слушатель) закрывают соединение, когда это необходимо. –

+0

Я настроил 'CachingConnectionFactory' для' JMSTemplate' для использования с Tibco EMS. Мой сервер сообщений работает на сервере tomcat. Даже после того, как tomcat изящно завершает работу, соединение по-прежнему не уничтожается в EMS. Есть ли обходной путь, чтобы закрыть его? – Manu

0

Приложение не требуется для закрытия сеанса при использовании DefaultMessageListenerContainer, оно создает необходимые сеансы и закрывает их во время выключения.

В моем понимании упомянутая вами заметка применяется, когда сеанс создается приложением, используя ссылку CachingConnectionFactory о том, какая весна не будет иметь никакой подсказки.

Смежные вопросы