Details
-
Improvement
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
2.9.0
-
Unknown
Description
The following sample Spring config sets up a camel-activemq component
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfigAmq" /> </bean> <bean id="jmsConfigAmq" class="org.apache.activemq.camel.component.ActiveMQConfiguration" > <property name="connectionFactory" ref="jmsPooledConnectionFactory" /> <property name="transacted" value="true"/> <!-- <property name="transactionManager" ref="jmsTransactionManager" /> --> <property name="cacheLevelName" value="CACHE_CONSUMER"/> </bean> <bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager"> <property name="connectionFactory" ref="jmsPooledConnectionFactory" /> </bean> <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61617" /> <property name="watchTopicAdvisories" value="false" /> </bean> <bean id="jmsPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" > <property name="maxConnections" value="1"/> <property name="connectionFactory" ref="jmsConnectionFactory"/> </bean>
The ActiveMQConfiguration sets transacted=true and configures for a JmsTransactionManager. Also, a PooledConnectionFactory is used.
The config for a camel-jms component would be similar.
The Spring JMS javadoc on AbstractPollingMessageListenerContainer.setTransactionManager states:
Note: Consider the use of local JMS transactions instead. Simply switch the "sessionTransacted" flag to "true" in order to use a locally transacted JMS Session for the entire receive processing, including any Session operations performed by a SessionAwareMessageListener (e.g. sending a response message).
It basically advises to only set transacted=true and don't specify a TX manager. The benefit of doing so is that the cacheLevel setting will be honored when using local transactions without a configured TX manager. When a TX manager is configured, no caching happens at DMLC level and its necessary to rely on a pooled connection factory. This is discussed here.
However right now its not possible to configure the cameljms or camel-activemq component to not use an external TX manager when transacted=true is set.
Even when setting lazyCreateTransactionManager=false.
In case of camel-activemq, it still creates a default JmsTransactionManager:
public PlatformTransactionManager getTransactionManager() { PlatformTransactionManager answer = super.getTransactionManager(); if (isTransacted() && answer == null) { // lets auto-default the transaction manager if its not specified answer = createTransactionManager(); setTransactionManager(answer); answer = getTransactionManager(); } return answer; }
In case of camel-jms it throws an exception:
PlatformTransactionManager tm = getTransactionManager(); if (tm != null) { container.setTransactionManager(tm); } else if (transacted) { throw new IllegalArgumentException("Property transacted is enabled but a transactionManager was not injected!"); }
We should allow for using transactions in camel-jms and camel-activemq without setting an external TX manager.
Attachments
Attachments
Issue Links
- relates to
-
AMQ-3861 Offer a way to not set a transaction manager in activemq-camel
- Resolved