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 The Transaction mediator supports distributed transactionsusing Java transaction API (JTA). JTA allows applications to perform a distributed transaction, that is, transactions that Distributed transactions 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 You can use the synapse Synapse configuration language to define the start , and end etc. of your transaction, pause transactions, and more. It is the responsibility of the user to define when to start, commit, or rollback roll back 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 a transaction for rollback transaction if a failure occurs.

...

Table of Contents
maxLevel3
minLevel3
styleborder:1
locationtop
typeflat
separatorpipe

Transaction Mediator

...

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

The action attribute has the following meanings:

Value

Meaning

new

Creates a new JTA transaction. Generates an error if a transaction already exist.

use-existing-or-new

Creates a new JTA transaction. Does nothing if a transaction exist.

fault-if-no-tx

Generates an error if no transaction exist. Does nothing if a transaction exist.

commit

Commits transaction. Generates an error if no transaction exist.

rollback

Rollback transaction. Generates an error if no transaction exist.

suspend

Suspends transaction. Generates an error if no transaction exist.

resume

Resumes transaction. Generates an error if no transaction exist.

Info
titleNote

To use the Transaction Mediator, you need to have a JTA provider in your environment, for example, JBoss.

Transaction Mediator Scenario

Use the following scenario to show how the Transaction Mediator works. Assume we have a record in one database and we want to delete that record from the first database and add it to the second database (these two databases can be run on the same server or they can be in two remote servers). The database tables are defined in such a way that the same entry cannot be added twice. So, in the successful scenario, the record will be deleted from the first table (of the first database) and will be added to the second table (of the second database). In a failure scenario (the record is already in the second database), no record will be deleted from first table and no record will be added into the second database.

System Requirements

Info
titleNote

This scenario applies to version 3.0. In versions after, there is a Transaction Manager in Carbon itself, so you don't have to put the ESB in an application server to get it working.

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

Info
titlteNote

JBoss server and the Derby database server have the characteristics mentioned above.

Running the Example

1. Unzip the WSO2 ESB distribution to a place of your choice. And then remove the geronimo-jta_1.1_spec-1.1.0.wso2v1.jar ( This JAR file can be found in $ESB_HOME/repository/components/plugins).

Info
titleTip

The reason is that the implementation of javax.transaction.UserTransaction of JTA provider (here JBoss) is used there and if they both are in class path, there is a classloading issue which causes the transaction mediator to fail.

2. Deploy the WSO2 ESB on JBoss AS. The JBoss installation path will be referred to as $JBOSS_HOME and the WSO2 ESB repo location as $CARBON_HOME.

3. Drop the derby client JARs (derby.jar, derbynet.jar and derbyclient.jar) into $CARBON_HOME/repository/components/lib folder and also into $JBOSS_HOME/server/default/lib (here is used the default JBoss configuration) folder.

4. We use here a sample similar to sample 361, and the full Synapse configuration is shown below. (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.

...

Scenario

Use the following scenario to see how the transaction mediator works. Assume we have a record in one database and we want to delete that record from the first database and add it to the second database (these two databases can be run on the same server or they can be in two remote servers). The database tables are defined in such a way that the same entry cannot be added twice. So, in the successful scenario, the record will be deleted from the first table (of the first database) and will be added to the second table (of the second database). In a failure scenario (the record is already in the second database), no record will be deleted from first table and no record will be added into the second database.

...

System Requirements

Info
titleNote

This scenario applies to version 3.0. In versions after, there is a Transaction Manager in Carbon itself, so you don't have to put the ESB in an application server to get it working.

  • Windows, Linux or Solaris operating systems with WSO2 ESB installed.
  • Derby Database (db-derby-10.5.1.1-bin version was used).
  • Apache ActiveMQ 5.3.1.

...

Running the Example

  1. Copy the Derby client JARs (derby.jar, derbynet.jar, and derbyclient.jar) from $DERBY_HOME/lib into <ESB_HOME>/repository/components/lib.
  2. Copy and paste the following configuration into the Synapse configuration in $ESB_HOME/repository/conf/synapse-config/synapse.xml.
    We use here a sample similar to sample 361. 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 that is already in the second database, the whole transaction will roll back.

    Code Block
    XML
    XML
    <definitions xmlns="http://ws.apache.org/ns/synapse">
       <sequence name="myFaultHandler">
            

...

  1. <log 

...

  1. level="

...

  1. custom"

...

  1. >
                <property 

...

  1. name="text" value="** Rollback Transaction**"/>
            </log>
           

...

  1.  <transaction 

...

  1. action="

...

  1. rollback"

...

  1. />
            <send/>
        </sequence>
        

...

  1. <sequence 

...

  1. name="main" onError="myFaultHandler">
            <in>
       

...

  1.  

...

  1.  

...

  1.        <send>
             

...

  1.        <endpoint>
                 

...

  1.        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                    

...

  1. </endpoint>
                </send>
            

...

  1. </in>
             <out>
                

...

  1. <transaction action="new"/>
                

...

  1. <log level="custom">
            

...

  1.         <property 

...

  1. name="text" value="** Reporting to the Database esbdb**"/>
            

...

  1.     </log>
                <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
     

...

  1.                <connection>
     

...

  1.                  

...

  1.   <pool>
                       

...

  1.  

...

  1.  

...

  1.  

...

  1.  

...

  1.  <dsName>java:jdbc/XADerbyDS</dsName>
                           

...

  1.  <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                            

...

  1. <url>localhost:1099</url>
                            <user>esb</user>
                   

...

  1.          <password>esb</password>
           

...

  1.              </

...

  1. pool>
                    

...

  1. </connection>
                    <statement>
     

...

  1.  

...

  1.  

...

  1.  

...

  1.  

...

  1.  

...

  1.  

...

  1.               <sql>delete 

...

  1. from company where name =?</sql>
            

...

  1.  

...

  1.  

...

  1.            <parameter expression="//m0:return/m1:symbol/child::text()"
        

...

  1.                    xmlns:m0="http://services.samples" 

...

  1. xmlns:m1="http://services.samples/xsd"
                             

...

  1.         type="VARCHAR"/>
                    

...

  1. </statement>
                

...

  1. </dbreport>
           

...

  1.      <log level="custom">
                    <property 

...

  1. name="text" value="** Reporting to the Database esbdb1**"/>
                </log>
          

...

  1.       <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
                

...

  1.     <connection>
                

...

  1.         <pool>
            

...

  1.                 <dsName>java:jdbc/XADerbyDS1</dsName>
        

...

  1.  

...

  1.  

...

  1.  

...

  1.  

...

  1.                 

...

  1. <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                    

...

  1.  

...

  1.        <url>localhost:1099</url>
                            

...

  1. <user>esb</user>
                           

...

  1.  

...

  1. <password>esb</password>
                     

...

  1.  

...

  1.   </pool>
                    </connection>
                

...

  1.     <statement>
                

...

  1.         <sql>INSERT into company 

...

  1. values (?,'c4',?)</

...

  1. sql>
                

...

  1.  

...

  1.        

...

  1. <parameter expression="//m0:return/m1:symbol/child::text()"
        

...

  1.      

...

5. To run the sample, you need two distributed Derby databases ("esbdb" and "esbdb1"). Refer here for details to set up the databases. The database table was created using the following SQL query.

Info
titleNote

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

...

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

Add few records to the two tables:

Database1:

...

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

Database2:

...

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

The order of the record matters.

6. Create two data source declarations for JBoss AS for the two distributed databases.

Datasource1:esb-derby-xa-ds.xml

...

  1. 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"
                          

...

  1.          

...

  1. type="DOUBLE"/>
                    

...

  1. </statement>
               

...

  1.  </dbreport>
                

...

  1. <transaction action="

...

  1. commit"

...

  1. />
               

...

  1.  <send/>
            </out>
        </sequence>
    

...

  1. </definitions>
    
  2. To run the sample, you need two distributed Derby databases ("esbdb" and "esbdb1"); see Setting up with Derby for details on setting up the databases. The database table was created using the following SQL query. Note that in the table schema, you cannot have the same entry twice.

    Code Block
    SQL
    SQL
    CREATE table company(name varchar(10) primary key, id varchar(10), price double);
    
  3. Add a few records to the two tables as follows (the order of the records matters):
    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);
    
  4. In the master-datasources.xml file located at $CARBON_HOME/repository/conf/datasources, create data source declarations for the distributed databases, ensuring that the datasource file names are *-xa-ds.xml:
    Datasource1: esb-derby-xa-ds.xml

    Code Block
    XML
    XML
    <?xml version="1.0" encoding="UTF-8"?>
    <datasources>
        <xa-datasource>
            <jndi-name>jdbc/

...

  1. 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"

...

  1. >esbdb</xa-datasource-property>
            <xa-datasource-property name="User">esb</xa-datasource-property>
            <xa-datasource-property name="Password">esb</xa-

...

  1. datasource-property>
            <metadata>
     

...

  1.      

...

  1.  

...

Info
titleNote

The two datasource file names should be *-xa-ds.xml.

...

  1.      <type-mapping>Derby</type-mapping>
            </metadata>
        </xa-datasource>
    </datasources>
    

    Datasource2: esb-derby1-xa-ds.xml

    Code Block
    XML
    XML
    <

...

  1. ?xml version="1.0" encoding="UTF-8"?>
    <datasources>
        <xa-datasource>
            <jndi-name>jdbc/XADerbyDS1</jndi-name>
            <isSameRM-override-value>false</isSameRM-override-value>
         

...

  1.  

...

  1.  

...

  1.  <xa-datasource-class>org.apache.derby.jdbc.ClientXADataSource</xa-datasource-class>
            

...

  1. <xa-datasource-property name="portNumber">1527</xa-datasource-property>
            

...

  1. <xa-datasource-

...

  1. property name="DatabaseName">esbdb1</xa-datasource-property>
            

...

  1. <xa-

...

  1. datasource-property name="User">esb</xa-datasource-property>
            

...

  1. <xa-datasource-property name="Password">esb</xa-datasource-property>
       

...

  1.      <metadata>
      

...

  1.           

...

  1. <type-mapping>Derby</type-mapping>
            </

...

7. Go into $JBOSS_HOME/bin and start the server. Run the run.sh (run.bat) script.

Info
titleNote

You need to set the CARBON_HOME environment variable pointing to the Carbon repository location.

...

  1. metadata>
        </xa-datasource>
    </datasources>
    
  2. Try the samples. Refer to sample set up guide to

...

  1. learn how

...

  1. to set up the server. Deploy the SimpleStockQuote service

...

  1. that comes with the WSO2 ESB samples.

Successful Scenario

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

2. Check both databases to see how the record is deleted from the first database and added to the second database.

Failure Scenario

1. Try to add an entry which is that already there exists in the second database. This time use Symbol the 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 rollbackrolls back. 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.