Transaction Control in Apache camel framework

Source: Internet
Author: User
Tags apache camel

This article briefly introduces how Apache camel implements transaction control on route. It first introduces the situation that the entire route only involves one transaction participant, and then introduces the situation that the route involves multiple transaction participants. camel implements transaction control through integration with Spring framework.

1. The entire route has only one transaction participant, "Local transaction". Here we use the JMS example. The backend MQ is activemq. The example is shown as follows: (the image is from camel in action)

The route code is as follows:

public class JMSTransaction extends RouteBuilder {    public void configure() throws Exception {        TProcessor0 p0 = new TProcessor0();        TProcessor1 p1 = new TProcessor1();        from("jms:queue:TOOL.DEFAULT").process(p0).process(p1).to("file:d:/temp/outbox");            }}

The spring configuration is as follows:

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:broker="http://activemq.apache.org/schema/core"       xsi:schemaLocation="       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd       http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">        <package>            com.test.camel.transaction.jms        </package>    </camelContext>        <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">        <property name="transacted" value="true"/>        <property name="transactionManager" ref="txManager"/>                </bean>    <bean id="txManager" class="org.springframework.jms.connection.JmsTransactionManager">        <property name="connectionFactory" ref="jmsConnectionFactory"/>    </bean>    <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">        <property name="brokerURL" value="tcp://localhost:61616"/>            </bean></beans>

The logic defined by route is to retrieve messages from the queue and perform a series of processing (process (P0 ). process (P1), <property name = "transacted" value = "true"/> means that the Message Access through this JMS is subject to transaction control. the preceding route throws an exception in process (P1), and txmanager performs rollback processing. (In activemq, messages are redelivery to the client six times by default. If an exception persists, the messages are placed in the deadletter Queue (activemq. (dlq). activemq is required in the configuration file of acivemq. the configuration in XML is as follows: (the non-persistent queue message error is also transferred to dead
Letter queue)

<Policyentry queue = ">">
<Deadletterstrategy>
<Shareddeadletterstrategy processnonpersistent = "true"/>
</Deadletterstrategy>

If <property name = "transacted" value = "false"/> is returned, messages are lost six times after being resold.

If the transaction participant in the above example is a database, the principle is similar, but the configured Transaction Manager is different, for example:

<Bean id = "txmanager" class = "org. springframework. JDBC. datasource. cetcetransactionmanager"/>

Examples of using activemq JMS in camel can refer to the http://blog.csdn.net/kkdelta/article/details/7237096

2. Global transactions in camel. A route contains multiple transaction participants, as shown in the following figure: (picture from camel in action)

Route is defined as follows:

public class XaTransaction extends RouteBuilder {    public void configure() throws Exception {        TProcessor1 p1 = new TProcessor1();        from("jms:queue:TOOL.DEFAULT")        .transacted()        .log("+++ before database +++")        .bean(SQLBean.class, "toSql")        .to("jdbc:myDataSource")        .process(p1)        .log("+++ after database +++");    }}public class SQLBean {    public String toSql(String str) {        //create table CamelTEST(msg varchar2(2000));        StringBuilder sb = new StringBuilder();        sb.append("INSERT INTO CamelTEST VALUES ('camel test')");        return sb.toString();    }}

The logic of route is to retrieve messages from queue, operate the database, and perform other subsequent operations (process (P1). If process (P1) throws an exception, message retrieval and database operation rollback,

If the entire route is successfully completed, the request message and database operation are submitted.

Here we use JTA Transaction Manager is atomikos, the corresponding jar package can be downloaded from here: http://download.csdn.net/detail/kkdelta/4056226

Home http://www.atomikos.com/Main/ProductsOverview of atomikos

The spring configuration is as follows:

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:broker="http://activemq.apache.org/schema/core"       xsi:schemaLocation="       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd       http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">       <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">        <package>            com.test.camel.transaction.xa        </package>    </camelContext>    <bean id="atomikosTransactionManager"          class="com.atomikos.icatch.jta.UserTransactionManager"          init-method="init" destroy-method="close" >        <!-- when close is called, should we force transactions to terminate or not? -->        <property name="forceShutdown" value="false"/>    </bean>    <!-- this is some atomikos setup you must do -->    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" >        <property name="transactionTimeout" value="300"/>    </bean>    <!-- this is some atomikos setup you must do -->    <bean id="connectionFactory"          class="com.atomikos.jms.AtomikosConnectionFactoryBean" >        <property name="uniqueResourceName" value="amq1"/>        <property name="xaConnectionFactory" ref="jmsXaConnectionFactory"/>    </bean>    <!-- this is the Spring JtaTransactionManager which under the hood uses Atomikos -->    <bean id="jtaTransactionManager"          class="org.springframework.transaction.jta.JtaTransactionManager" >        <property name="transactionManager" ref="atomikosTransactionManager"/>        <property name="userTransaction" ref="atomikosUserTransaction"/>    </bean>    <!-- Is the ConnectionFactory to connect to the JMS broker -->    <!-- notice how we must use the XA connection factory -->    <bean id="jmsXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory" >        <property name="brokerURL" value="tcp://localhost:61616"/>    </bean>    <!-- define the activemq Camel component so we can integrate with the AMQ broker below -->    <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent" >        <property name="transacted" value="true"/>        <property name="transactionManager" ref="jtaTransactionManager"/>    </bean>   <bean id="myDataSource"       class="com.atomikos.jdbc.AtomikosDataSourceBean"       init-method="init" destroy-method="close">        <!-- set an arbitrary but unique name for the datasource -->       <property name="uniqueResourceName"><value>XADBMS</value></property>       <property name="xaDataSourceClassName">          <value>oracle.jdbc.xa.client.OracleXADataSource</value>       </property>       <property name="xaProperties">                 <props>                         <prop key="user">xxx</prop>                         <prop key="password">xxx</prop>                         <prop key="URL">jdbc:oracle:thin:@147.151.240.xxx:1521:orcl</prop>                </props>       </property>          <property name="poolSize" value="1"/>    </bean>    </beans>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.