You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Colin Ruthven <ru...@attglobal.net> on 2009/03/23 17:06:28 UTC
Non-Spring Transaction Manager
Is it possible to use transactions in Camel messaging (eg JMS) without
Spring intruding? Camel may use Spring underneath the covers but I don't
want to use it inside my application.
Or at least only use Camel API's to do this or be able to plug other
solutions in.
The documentation seems to go both ways, suggesting that Spring is the
"default" but in other places it looks like that's the only approach
available.
Any comments appreciated.
Thanks,
Colin
Re: Non-Spring Transaction Manager
Posted by James Strachan <ja...@gmail.com>.
2009/3/24 James Strachan <ja...@gmail.com>:
> I think the issue is that you configure the configuration of the JMS
> component with the transaction manager after you've created the JMS
> endpoint. Try moving the configuration of the JMS component to the
> setup method; before you create any endpoints?
Just for some background; when you create a JmsEndpoint it takes its
own copy of the JmsConfiguration bean so that you can then configure
the JmsEndpoint to your hearts content - but you don't necesarily
reconfigure other JMS endpoints
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://fusesource.com/
Re: Non-Spring Transaction Manager
Posted by James Strachan <ja...@gmail.com>.
I think the issue is that you configure the configuration of the JMS
component with the transaction manager after you've created the JMS
endpoint. Try moving the configuration of the JMS component to the
setup method; before you create any endpoints?
2009/3/24 Colin Ruthven <ru...@attglobal.net>:
> Thought you'd ask. :)
> It reflects some exploration of a couple of Camel API's, rather than being
> stripped to a minimum.
>
> Thanks again for helping.
> Colin
>
> public class DataCamelTest extends TestCase{
> CamelContext context;
>
> ProducerTemplate prod;
> Endpoint end;
> public DataCamelTest(String arg0) {
> super(arg0);
> }
>
> protected void setUp() throws Exception {
> super.setUp();
> context = new DefaultCamelContext();
> context.start();
> context.addComponent("activemq",
> ActiveMQComponent.activeMQComponent("tcp://localhost:61616"));
>
> prod = new DefaultProducerTemplate<Exchange>(context);
> end = context.getComponent("activemq").createEndpoint("TEST.FOO");
> context.addEndpoint("end", end );
> }
>
> public void testProcess() throws InterruptedException {
> //System.out.println(producer);
> //assertTrue(producer!=null);
>
> ApplicationContext spring = new
> ClassPathXmlApplicationContext("applicationContext.xml");
> JtaTransactionManager transactionManager = (JtaTransactionManager)
> spring.getBean("jtaTransactionManager");
> ((JmsComponent)
> context.getComponent("activemq")).getConfiguration().setTransactionManager(transactionManager);
> ((JmsComponent)
> context.getComponent("activemq")).getConfiguration().setTransacted(true);
>
> Transaction tx = null;
> Jotm jotm = null;
> TransactionManager tm = null;
> try {
> jotm = new Jotm(true, false);
> tm = jotm.getTransactionManager();
> tm.begin(); prod.sendBody(
> "activemq:TEST.FOO", "Hello");
> prod.sendBody( end, "Hello1");
>
> tm.rollback();
>
> } catch (IllegalStateException e1) {
> e1.printStackTrace();
> } catch (SystemException e1) {
> e1.printStackTrace();
> } catch (NamingException e) {
> e.printStackTrace();
> } catch (NotSupportedException e) {
> e.printStackTrace();
> }
> Endpoint endpoint = context.getEndpoint("activemq:TEST.FOO");
> Consumer consumer = null;
>
> Processor my = new MyProcessor();
> try {
> consumer = endpoint.createConsumer(my);
> consumer.start(); } catch (Exception e) {
> e.printStackTrace();
> }
> try {
> Thread.sleep(1000000);
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> }
>
> public static class MyProcessor implements Processor {
> private int count;
> public void process(Exchange exchange) throws Exception {
> Message message = exchange.getIn();
> System.out.println(message.getBody()); }
> }
> }
>
>
> James Strachan wrote:
>>
>> Whats the code using the producer look like?
>>
>> 2009/3/24 Colin Ruthven <ru...@attglobal.net>:
>>
>>>
>>> Thanks. That got me further.
>>>
>>> Assuming I use JOTM and use it for transaction control within Java, I
>>> attempted the following applicationContext.xml :
>>>
>>> <context:component-scan base-package="org.apache.camel.spring.produce"/>
>>> <camel:camelContext id="camel">
>>> </camel:camelContext>
>>>
>>> <bean id="jotm"
>>> class="org.springframework.transaction.jta.JotmFactoryBean"/>
>>>
>>> <bean id="jtaTransactionManager"
>>> class="org.springframework.transaction.jta.JtaTransactionManager">
>>> <property name="userTransaction"><ref local="jotm"/></property>
>>> </bean>
>>>
>>> <bean id="jmsConnectionFactory"
>>> class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
>>> </bean>
>>> <bean id="jmsComponent"
>>> class="org.apache.camel.component.jms.JmsComponent">
>>> <property name="transactionManager"><ref
>>> local="jtaTransactionManager"/></property>
>>> <property name="transacted" value="true"/>
>>> <property name="connectionFactory"><ref
>>> local="jmsConnectionFactory"/>
>>> </property>
>>> </bean>
>>>
>>> I have a unit test successfully sending and receiving to an ActiveMQ
>>> broker
>>> outside the VM.
>>>
>>> To that test I created a JOTM TransactionManager, Transaction then
>>> prefixed
>>> the producer.sendBody() with a begin transaction and followed the send
>>> with
>>> a rollback.
>>> The message still gets sent.
>>>
>>> By the looks of stdout Spring is finding the JTA and JOTM is starting.
>>>
>>> I'm using Camel 1.6 and ActiveMQ 5.2
>>>
>>> What am I missing?
>>>
>>> Thanks,
>>> Colin
>>>
>>> James Strachan wrote:
>>>
>>>>
>>>> 2009/3/23 Colin Ruthven <ru...@attglobal.net>:
>>>>
>>>>
>>>>>
>>>>> I don't specifically have one in mind.
>>>>>
>>>>> In exploring Camel I found that one can perform the basic messaging
>>>>> functions in Java using Camel API's only but got messy with
>>>>> transactions.
>>>>>
>>>>> My preference would be for Camel to expose a JTA. If that transparently
>>>>> invoked Spring TX that would be fine - analogous to the various
>>>>> components
>>>>> wrapping Spring but not exposing it directly in Java.
>>>>>
>>>>>
>>>>
>>>> BTW you can ignore the Spring IoC stuff if you like and just use Java
>>>> to wire stuff together and populate JNDI - or use Guice or whatever.
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>> What other options exist outside a container (or inside) for
>>>>> transaction
>>>>> support that would work with Camel?
>>>>>
>>>>>
>>>>
>>>> The JMS component & endpoints relies on the Spring JMS abstractions
>>>> (JmsTemplate and MessageListenerContainer classes) which use Spring
>>>> transactions under the covers. However its pretty trivial to configure
>>>> the JmsComponent to use Spring's JtaTransactionManager then you can do
>>>> whatever you like with JTA and all the JMS endpoints will be
>>>> auto-enlisted in JTA for you.
>>>>
>>>> However one of the main benefits of the spring transactions support
>>>> (other than the proxy/aop/annotation stuff) is that its trivial to
>>>> switch between XA/JTA and lightweight transactions (e.g. pure JMS
>>>> transactions or pure JDBC transactions) without the J2EE Transaction
>>>> Manager / JCA / XA overhead.
>>>>
>>>>
>>>>
>>
>>
>>
>>
>
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://fusesource.com/
Re: Non-Spring Transaction Manager
Posted by Colin Ruthven <ru...@attglobal.net>.
Thought you'd ask. :)
It reflects some exploration of a couple of Camel API's, rather than
being stripped to a minimum.
Thanks again for helping.
Colin
public class DataCamelTest extends TestCase{
CamelContext context;
ProducerTemplate prod;
Endpoint end;
public DataCamelTest(String arg0) {
super(arg0);
}
protected void setUp() throws Exception {
super.setUp();
context = new DefaultCamelContext();
context.start();
context.addComponent("activemq",
ActiveMQComponent.activeMQComponent("tcp://localhost:61616"));
prod = new DefaultProducerTemplate<Exchange>(context);
end = context.getComponent("activemq").createEndpoint("TEST.FOO");
context.addEndpoint("end", end );
}
public void testProcess() throws InterruptedException {
//System.out.println(producer);
//assertTrue(producer!=null);
ApplicationContext spring = new
ClassPathXmlApplicationContext("applicationContext.xml");
JtaTransactionManager transactionManager =
(JtaTransactionManager) spring.getBean("jtaTransactionManager");
((JmsComponent)
context.getComponent("activemq")).getConfiguration().setTransactionManager(transactionManager);
((JmsComponent)
context.getComponent("activemq")).getConfiguration().setTransacted(true);
Transaction tx = null;
Jotm jotm = null;
TransactionManager tm = null;
try {
jotm = new Jotm(true, false);
tm = jotm.getTransactionManager();
tm.begin();
prod.sendBody( "activemq:TEST.FOO", "Hello");
prod.sendBody( end, "Hello1");
tm.rollback();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (SystemException e1) {
e1.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
} catch (NotSupportedException e) {
e.printStackTrace();
}
Endpoint endpoint = context.getEndpoint("activemq:TEST.FOO");
Consumer consumer = null;
Processor my = new MyProcessor();
try {
consumer = endpoint.createConsumer(my);
consumer.start();
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class MyProcessor implements Processor {
private int count;
public void process(Exchange exchange) throws Exception {
Message message = exchange.getIn();
System.out.println(message.getBody());
}
}
}
James Strachan wrote:
> Whats the code using the producer look like?
>
> 2009/3/24 Colin Ruthven <ru...@attglobal.net>:
>
>> Thanks. That got me further.
>>
>> Assuming I use JOTM and use it for transaction control within Java, I
>> attempted the following applicationContext.xml :
>>
>> <context:component-scan base-package="org.apache.camel.spring.produce"/>
>> <camel:camelContext id="camel">
>> </camel:camelContext>
>>
>> <bean id="jotm"
>> class="org.springframework.transaction.jta.JotmFactoryBean"/>
>>
>> <bean id="jtaTransactionManager"
>> class="org.springframework.transaction.jta.JtaTransactionManager">
>> <property name="userTransaction"><ref local="jotm"/></property>
>> </bean>
>>
>> <bean id="jmsConnectionFactory"
>> class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
>> </bean>
>> <bean id="jmsComponent"
>> class="org.apache.camel.component.jms.JmsComponent">
>> <property name="transactionManager"><ref
>> local="jtaTransactionManager"/></property>
>> <property name="transacted" value="true"/>
>> <property name="connectionFactory"><ref local="jmsConnectionFactory"/>
>> </property>
>> </bean>
>>
>> I have a unit test successfully sending and receiving to an ActiveMQ broker
>> outside the VM.
>>
>> To that test I created a JOTM TransactionManager, Transaction then prefixed
>> the producer.sendBody() with a begin transaction and followed the send with
>> a rollback.
>> The message still gets sent.
>>
>> By the looks of stdout Spring is finding the JTA and JOTM is starting.
>>
>> I'm using Camel 1.6 and ActiveMQ 5.2
>>
>> What am I missing?
>>
>> Thanks,
>> Colin
>>
>> James Strachan wrote:
>>
>>> 2009/3/23 Colin Ruthven <ru...@attglobal.net>:
>>>
>>>
>>>> I don't specifically have one in mind.
>>>>
>>>> In exploring Camel I found that one can perform the basic messaging
>>>> functions in Java using Camel API's only but got messy with transactions.
>>>>
>>>> My preference would be for Camel to expose a JTA. If that transparently
>>>> invoked Spring TX that would be fine - analogous to the various
>>>> components
>>>> wrapping Spring but not exposing it directly in Java.
>>>>
>>>>
>>> BTW you can ignore the Spring IoC stuff if you like and just use Java
>>> to wire stuff together and populate JNDI - or use Guice or whatever.
>>>
>>>
>>>
>>>
>>>> What other options exist outside a container (or inside) for transaction
>>>> support that would work with Camel?
>>>>
>>>>
>>> The JMS component & endpoints relies on the Spring JMS abstractions
>>> (JmsTemplate and MessageListenerContainer classes) which use Spring
>>> transactions under the covers. However its pretty trivial to configure
>>> the JmsComponent to use Spring's JtaTransactionManager then you can do
>>> whatever you like with JTA and all the JMS endpoints will be
>>> auto-enlisted in JTA for you.
>>>
>>> However one of the main benefits of the spring transactions support
>>> (other than the proxy/aop/annotation stuff) is that its trivial to
>>> switch between XA/JTA and lightweight transactions (e.g. pure JMS
>>> transactions or pure JDBC transactions) without the J2EE Transaction
>>> Manager / JCA / XA overhead.
>>>
>>>
>>>
>
>
>
>
Re: Non-Spring Transaction Manager
Posted by James Strachan <ja...@gmail.com>.
Whats the code using the producer look like?
2009/3/24 Colin Ruthven <ru...@attglobal.net>:
> Thanks. That got me further.
>
> Assuming I use JOTM and use it for transaction control within Java, I
> attempted the following applicationContext.xml :
>
> <context:component-scan base-package="org.apache.camel.spring.produce"/>
> <camel:camelContext id="camel">
> </camel:camelContext>
>
> <bean id="jotm"
> class="org.springframework.transaction.jta.JotmFactoryBean"/>
>
> <bean id="jtaTransactionManager"
> class="org.springframework.transaction.jta.JtaTransactionManager">
> <property name="userTransaction"><ref local="jotm"/></property>
> </bean>
>
> <bean id="jmsConnectionFactory"
> class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
> </bean>
> <bean id="jmsComponent"
> class="org.apache.camel.component.jms.JmsComponent">
> <property name="transactionManager"><ref
> local="jtaTransactionManager"/></property>
> <property name="transacted" value="true"/>
> <property name="connectionFactory"><ref local="jmsConnectionFactory"/>
> </property>
> </bean>
>
> I have a unit test successfully sending and receiving to an ActiveMQ broker
> outside the VM.
>
> To that test I created a JOTM TransactionManager, Transaction then prefixed
> the producer.sendBody() with a begin transaction and followed the send with
> a rollback.
> The message still gets sent.
>
> By the looks of stdout Spring is finding the JTA and JOTM is starting.
>
> I'm using Camel 1.6 and ActiveMQ 5.2
>
> What am I missing?
>
> Thanks,
> Colin
>
> James Strachan wrote:
>>
>> 2009/3/23 Colin Ruthven <ru...@attglobal.net>:
>>
>>>
>>> I don't specifically have one in mind.
>>>
>>> In exploring Camel I found that one can perform the basic messaging
>>> functions in Java using Camel API's only but got messy with transactions.
>>>
>>> My preference would be for Camel to expose a JTA. If that transparently
>>> invoked Spring TX that would be fine - analogous to the various
>>> components
>>> wrapping Spring but not exposing it directly in Java.
>>>
>>
>> BTW you can ignore the Spring IoC stuff if you like and just use Java
>> to wire stuff together and populate JNDI - or use Guice or whatever.
>>
>>
>>
>>>
>>> What other options exist outside a container (or inside) for transaction
>>> support that would work with Camel?
>>>
>>
>> The JMS component & endpoints relies on the Spring JMS abstractions
>> (JmsTemplate and MessageListenerContainer classes) which use Spring
>> transactions under the covers. However its pretty trivial to configure
>> the JmsComponent to use Spring's JtaTransactionManager then you can do
>> whatever you like with JTA and all the JMS endpoints will be
>> auto-enlisted in JTA for you.
>>
>> However one of the main benefits of the spring transactions support
>> (other than the proxy/aop/annotation stuff) is that its trivial to
>> switch between XA/JTA and lightweight transactions (e.g. pure JMS
>> transactions or pure JDBC transactions) without the J2EE Transaction
>> Manager / JCA / XA overhead.
>>
>>
>
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://fusesource.com/
Re: Non-Spring Transaction Manager
Posted by Colin Ruthven <ru...@attglobal.net>.
Thanks. That got me further.
Assuming I use JOTM and use it for transaction control within Java, I
attempted the following applicationContext.xml :
<context:component-scan base-package="org.apache.camel.spring.produce"/>
<camel:camelContext id="camel">
</camel:camelContext>
<bean id="jotm"
class="org.springframework.transaction.jta.JotmFactoryBean"/>
<bean id="jtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction"><ref local="jotm"/></property>
</bean>
<bean id="jmsConnectionFactory"
class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
</bean>
<bean id="jmsComponent"
class="org.apache.camel.component.jms.JmsComponent">
<property name="transactionManager"><ref
local="jtaTransactionManager"/></property>
<property name="transacted" value="true"/>
<property name="connectionFactory"><ref
local="jmsConnectionFactory"/> </property>
</bean>
I have a unit test successfully sending and receiving to an ActiveMQ
broker outside the VM.
To that test I created a JOTM TransactionManager, Transaction then
prefixed the producer.sendBody() with a begin transaction and followed
the send with a rollback.
The message still gets sent.
By the looks of stdout Spring is finding the JTA and JOTM is starting.
I'm using Camel 1.6 and ActiveMQ 5.2
What am I missing?
Thanks,
Colin
James Strachan wrote:
> 2009/3/23 Colin Ruthven <ru...@attglobal.net>:
>
>> I don't specifically have one in mind.
>>
>> In exploring Camel I found that one can perform the basic messaging
>> functions in Java using Camel API's only but got messy with transactions.
>>
>> My preference would be for Camel to expose a JTA. If that transparently
>> invoked Spring TX that would be fine - analogous to the various components
>> wrapping Spring but not exposing it directly in Java.
>>
>
> BTW you can ignore the Spring IoC stuff if you like and just use Java
> to wire stuff together and populate JNDI - or use Guice or whatever.
>
>
>
>> What other options exist outside a container (or inside) for transaction
>> support that would work with Camel?
>>
>
> The JMS component & endpoints relies on the Spring JMS abstractions
> (JmsTemplate and MessageListenerContainer classes) which use Spring
> transactions under the covers. However its pretty trivial to configure
> the JmsComponent to use Spring's JtaTransactionManager then you can do
> whatever you like with JTA and all the JMS endpoints will be
> auto-enlisted in JTA for you.
>
> However one of the main benefits of the spring transactions support
> (other than the proxy/aop/annotation stuff) is that its trivial to
> switch between XA/JTA and lightweight transactions (e.g. pure JMS
> transactions or pure JDBC transactions) without the J2EE Transaction
> Manager / JCA / XA overhead.
>
>
Re: Non-Spring Transaction Manager
Posted by James Strachan <ja...@gmail.com>.
2009/3/23 Colin Ruthven <ru...@attglobal.net>:
> I don't specifically have one in mind.
>
> In exploring Camel I found that one can perform the basic messaging
> functions in Java using Camel API's only but got messy with transactions.
>
> My preference would be for Camel to expose a JTA. If that transparently
> invoked Spring TX that would be fine - analogous to the various components
> wrapping Spring but not exposing it directly in Java.
BTW you can ignore the Spring IoC stuff if you like and just use Java
to wire stuff together and populate JNDI - or use Guice or whatever.
> What other options exist outside a container (or inside) for transaction
> support that would work with Camel?
The JMS component & endpoints relies on the Spring JMS abstractions
(JmsTemplate and MessageListenerContainer classes) which use Spring
transactions under the covers. However its pretty trivial to configure
the JmsComponent to use Spring's JtaTransactionManager then you can do
whatever you like with JTA and all the JMS endpoints will be
auto-enlisted in JTA for you.
However one of the main benefits of the spring transactions support
(other than the proxy/aop/annotation stuff) is that its trivial to
switch between XA/JTA and lightweight transactions (e.g. pure JMS
transactions or pure JDBC transactions) without the J2EE Transaction
Manager / JCA / XA overhead.
--
James
-------
http://macstrac.blogspot.com/
Open Source Integration
http://fusesource.com/
Re: Non-Spring Transaction Manager
Posted by Colin Ruthven <ru...@attglobal.net>.
I don't specifically have one in mind.
In exploring Camel I found that one can perform the basic messaging
functions in Java using Camel API's only but got messy with transactions.
My preference would be for Camel to expose a JTA. If that transparently
invoked Spring TX that would be fine - analogous to the various
components wrapping Spring but not exposing it directly in Java.
What other options exist outside a container (or inside) for transaction
support that would work with Camel?
Thank you for responding,
Colin
Claus Ibsen wrote:
> On Mon, Mar 23, 2009 at 5:06 PM, Colin Ruthven <ru...@attglobal.net> wrote:
>
>> Is it possible to use transactions in Camel messaging (eg JMS) without
>> Spring intruding? Camel may use Spring underneath the covers but I don't
>> want to use it inside my application.
>>
>> Or at least only use Camel API's to do this or be able to plug other
>> solutions in.
>>
> Hi
>
> camel-jms uses spring-jms under the covers. And the TX support we have
> in Camel relies on Spring TX as well.
>
> But you can disable the error handler completely in Camel and let
> whatever external system you use handle the TX.
>
> In java DSL:
> errorHandler(noErrorHandler));
>
>
> In Spring DSL its something like this (I sit with laptop in hand and
> dont have code editor open)
> <bean id="myNoErrorHandler"
> class="org.apache.camel.builder.NoErrorHandlerBuilder"/>
>
> <camel errorHandlerRef="myNoErrorHandler" ...>
>
> </camel>
>
>
>
>
>> The documentation seems to go both ways, suggesting that Spring is the
>> "default" but in other places it looks like that's the only approach
>> available.
>>
> Usually Spring TX is very flexible, so you can wire it up to integrate
> with your external system for the TX management.
>
>
> What kind of other framework/system do you want to handle the TX?
>
>
>
>> Any comments appreciated.
>>
>> Thanks,
>> Colin
>>
>>
>>
>>
>
>
>
>
Re: Non-Spring Transaction Manager
Posted by Claus Ibsen <cl...@gmail.com>.
On Mon, Mar 23, 2009 at 5:06 PM, Colin Ruthven <ru...@attglobal.net> wrote:
> Is it possible to use transactions in Camel messaging (eg JMS) without
> Spring intruding? Camel may use Spring underneath the covers but I don't
> want to use it inside my application.
>
> Or at least only use Camel API's to do this or be able to plug other
> solutions in.
Hi
camel-jms uses spring-jms under the covers. And the TX support we have
in Camel relies on Spring TX as well.
But you can disable the error handler completely in Camel and let
whatever external system you use handle the TX.
In java DSL:
errorHandler(noErrorHandler));
In Spring DSL its something like this (I sit with laptop in hand and
dont have code editor open)
<bean id="myNoErrorHandler"
class="org.apache.camel.builder.NoErrorHandlerBuilder"/>
<camel errorHandlerRef="myNoErrorHandler" ...>
</camel>
>
> The documentation seems to go both ways, suggesting that Spring is the
> "default" but in other places it looks like that's the only approach
> available.
Usually Spring TX is very flexible, so you can wire it up to integrate
with your external system for the TX management.
What kind of other framework/system do you want to handle the TX?
>
> Any comments appreciated.
>
> Thanks,
> Colin
>
>
>
--
Claus Ibsen
Apache Camel Committer
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/