Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

A new synapse mediator (Transaction Mediator) has been added to support the distributed transactions using Java transaction API(JTA). JTA allows applications to perform a distributed transaction, that is, transactions that access and update data on two or more networked computer resources (an example would be to have two databases or a database and a message queue such as JMS). This mediator can be used to perform a distributed transaction. The synapse configuration has been extended to add explicit transaction markers. This means that you can use the synapse configuration language to define the start, end etc. of your transaction. It is the responsibility of the user to define when to start, commit or rollback the transaction. For example, you can mark the start of a transaction at the start of a database commit, end of the transaction at the end of the database commit and you can mark rollback transaction if a failure occurs.

...

Table of Contents
maxLevel3
minLevel3

...

styleborder:1
locationtop
typeflat
separatorpipe

...

Transaction Mediator Configuration

Code Block
XML
XML

<transaction action="new|use-existing-or-new|fault-if-no-tx|commit|rollback|suspend|resume"/>

...

Since the Transaction Mediator is implemented using JTA, you need to have a JTA provider. Here we used JBoss J2EE application server (Application Server (JBoss AS), which implements the transaction support through Arjuna TS) , as the JTA provider, so it is necessary to deploy the WSO2 ESB in JBoss Application server ( AS). Use Apache Derby as the database server.

...

4. We use here a sample similar to #361 sample 361, and the full Synapse configuration is shown below. (you You can directly paste the following configuration into synapse configuration in $ESB_HOME/repository/conf/synapse-config/synapse.xml). In the "In" sequence, we will send a message to the service and in the "Out" sequence we will delete an entry from the first database and update the second database with that entry. If we try to add an entry, which is already there in the second database, the whole transaction will rollback.

Code Block
XML
XML

<definitions xmlns="http://ws.apache.org/ns/synapse">
   <sequence name="myFaultHandler">
        <log level="custom">
            <property name="text" value="** Rollback Transaction**"/>
        </log>
        <transaction action="rollback"/>
        <send/>
    </sequence>
    <sequence name="main" onError="myFaultHandler">
        <in>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>
         <out>
            <transaction action="new"/>
            <log level="custom">
                <property name="text" value="** Reporting to the Database esbdb**"/>
            </log>
            <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <dsName>java:jdbc/XADerbyDS</dsName>
                        <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                        <url>localhost:1099</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                     <sql>delete from company where name =?</sql>
                     <parameter expression="//m0:return/m1:symbol/child::text()"
                       xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd"
                                 type="VARCHAR"/>
                </statement>
            </dbreport>
            <log level="custom">
                <property name="text" value="** Reporting to the Database esbdb1**"/>
            </log>
            <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <dsName>java:jdbc/XADerbyDS1</dsName>
                        <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                        <url>localhost:1099</url>
                        <user>esb</user>
                        <password>esb</password>
                    </pool>
                </connection>
                <statement>
                    <sql>INSERT into company values (?,'c4',?)</sql>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
         xmlns:m1="http://services.samples/xsd" xmlns:m0="http://services.samples"
                               type="VARCHAR"/>
                    <parameter expression="//m0:return/m1:last/child::text()"
         xmlns:m1="http://services.samples/xsd" xmlns:m0="http://services.samples"
                               type="DOUBLE"/>
                </statement>
            </dbreport>
            <transaction action="commit"/>
            <send/>
        </out>
    </sequence>
</definitions>

...

Info
titleNote

In the table schema we cannot have the same entry twice.

Code Block
SQL
SQL

CREATE table company(name varchar(10) primary key, id varchar(10), price double);

...

Database1:

Code Block
SQL
SQL

INSERT into company values ('IBM','c1',0.0);
INSERT into company values ('SUN','c2',0.0);

Database2:

Code Block
SQL
SQL

INSERT into company values ('SUN','c2',0.0);
INSERT into company values ('MSFT','c3',0.0);

...

Datasource1:esb-derby-xa-ds.xml

Code Block
XML
XML

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
    <xa-datasource>
        <jndi-name>jdbc/XADerbyDS</jndi-name>
        <isSameRM-override-value>false</isSameRM-override-value>
        <xa-datasource-class>org.apache.derby.jdbc.ClientXADataSource</xa-datasource-class>
        <xa-datasource-property name="portNumber">1527</xa-datasource-property>
        <xa-datasource-property name="DatabaseName">esbdb</xa-datasource-property>
        <xa-datasource-property name="User">esb</xa-datasource-property>
        <xa-datasource-property name="Password">esb</xa-datasource-property>
        <metadata>
            <type-mapping>Derby</type-mapping>
        </metadata>
    </xa-datasource>
</datasources>

Datasource2:esb-derby1-xa-ds.xml

Code Block
XML
XML

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
    <xa-datasource>
        <jndi-name>jdbc/XADerbyDS1</jndi-name>
        <isSameRM-override-value>false</isSameRM-override-value>
        <xa-datasource-class>org.apache.derby.jdbc.ClientXADataSource</xa-datasource-class>
        <xa-datasource-property name="portNumber">1527</xa-datasource-property>
        <xa-datasource-property name="DatabaseName">esbdb1</xa-datasource-property>
        <xa-datasource-property name="User">esb</xa-datasource-property>
        <xa-datasource-property name="Password">esb</xa-datasource-property>
        <metadata>
            <type-mapping>Derby</type-mapping>
        </metadata>
    </xa-datasource>
</datasources>

...

Drop the two datasource declarations above into $JBOSS_HOME/server/default/deploy folder. Map the above jndi names: drop the following jboss-web.xml configuration into $JBOSS_HOME/serer/default/deploy/esb.war/WEB-INF/.

Code Block
XML
XML

<!DOCTYPE jboss-web PUBLIC
         "-//JBoss//DTD Web Application 5.0//EN"
         "http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">
 <jboss-web>
     <resource-ref>
         <res-ref-name>jdbc/XADerbyDS</res-ref-name>
         <jndi-name>java:/XADerbyDS</jndi-name>
     </resource-ref>
     <resource-ref>
         <res-ref-name>jdbc/XADerbyDS1</res-ref-name>
         <jndi-name>java:/XADerbyDS1</jndi-name>
     </resource-ref>
 </jboss-web>

...

1. To remove the IBM record from the first database and add it to the second database, run the sample with the following options.

Code Block

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService
-Dtrpurl=http://localhost:8280/ -Dsymbol=IBM

...

1. Try to add an entry which is already there in the second database. This time use Symbol SUN.

Code Block

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService
-Dtrpurl=http://localhost:8280/ -Dsymbol=SUN

2. You will see how the fault sequence is executed and the whole transaction rollback. Check both databases again; there is no record deleted from the first database and no record added into the second database.

Excerpt
hiddentrue

Description of transaction mediator in example in WSO2 ESB.