activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hengyunabc <hengyun...@gmail.com>
Subject Re: The cacmel.xml can not work in ActiveMQ5.8, works fine in ActiveMQ5.5
Date Mon, 13 May 2013 19:08:12 GMT
OK, I have found the reason.
ActiveMQ5.5.0 use spring 3.0.3 and camel 2.7.0, 
ActiveMQ5.8.0 use spring 3.1.3 and camel 2.10.3.

In spring 3.0.3 and camel 2.7.0, default cache level is CACHE_CONSUMER.
In spring 3.1.3 and camel 2.10.3, default cache level is CACHE_AUTO.

How the CACHE_AUTO works? See here:
DefaultMessageListenerContainer´╝Ü
public void initialize() {
    // Adapt default cache level.
    if (this.cacheLevel == CACHE_AUTO) {
        this.cacheLevel = (getTransactionManager() != null ? CACHE_NONE :
CACHE_CONSUMER);
    }

*So, in ActiveMQ5.8.0, when we use the TransactionManager in camel.xml, the
cache level will be CACHE_NONE.*

When cache level is CACHE_NONE,  the consumer of the ActiveMQComponent will
be set to null.
DefaultMessageListenerContainer´╝Ü
privatevoidinitResourcesIfNecessary() throwsJMSException {
    if(getCacheLevel() <= CACHE_CONNECTION) {
        updateRecoveryMarker();
    }
    else{
        if(this.session == null&& getCacheLevel() >= CACHE_SESSION) {
            updateRecoveryMarker();
            this.session = createSession(getSharedConnection());
        }
        if(this.consumer == null&& getCacheLevel() >= CACHE_CONSUMER) {
            this.consumer = createListenerConsumer(this.session);
            synchronized(lifecycleMonitor) {
                registeredWithDestination++;
            }
        }
    }
}

And then, in function
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute,
will 
exec this:
            MessageConsumer consumerToUse = consumer;
            if (consumerToUse == null) {
                consumerToUse = createListenerConsumer(sessionToUse);
                consumerToClose = consumerToUse;
            }
finally will close the consumer:
JmsUtils.closeMessageConsumer(consumerToClose);

*In summary, when we use TransactionManager, the resource will be destory,
and then create again in every transaction.*

Another place worthy attention is that *we should configure the
connectionFactory for the ActiveMQComponent explicitly. If we do not, the
connectionFactory will be a PooledConnectionFactory!! * The
connectionFactory which configure in TransactionManager did not works.

This is why the log show: 
  You cannot create a durable subscriber without specifying a unique
clientID on a Connection

So, we have batter to configure the connectionFactory and cacheLevel of the
JMSComponent carefully.
If unnecessary ,do not use TransactionManager.
The simplest configuration is:
	<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
		<route>
			<description>Example Camel Route 1</description>
			<from
			
uri="jms:topic:spring_test_topic?clientId=1&amp;durableSubscriptionName=bar1"
/>
			<to uri="jms:queue:spring_test_queue1" />
		</route>
	</camelContext>

	<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>

	<bean id="jmsPooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory"
		init-method="start" destroy-method="stop">
		<property name="connectionFactory" ref="jmsConnectionFactory" />
	</bean>

	<bean id="jms"
class="org.apache.activemq.camel.component.ActiveMQComponent">
		<property name="cacheLevel" value="3" />
		<property name="connectionFactory" ref="jmsPooledConnectionFactory" />
	</bean>



--
View this message in context: http://activemq.2283324.n4.nabble.com/The-cacmel-xml-can-not-work-in-ActiveMQ5-8-works-fine-in-ActiveMQ5-5-tp4666808p4666978.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.

Mime
View raw message