Using JTA Transactions with SOAP, REST and other Proxy Services

Sample Number

105

Level

Intermediary

Description

This sample demonstrates the usage of UltraESB to create JTA XA transactional Proxy Services for SOAP, REST and other technologies

Use Case

The UltraESB transports are capable of reading a message within a resource local (i.e. JMS/JDBC local) or JTA XA transaction - to ensure that a rollback on the message during processing will put the message back into the original location for re-processing. Additionally the UltraESB can perform transactional mediation for messages received over any transport - such as HTTP/S, and this sample describes such examples.

In this example, we will perform a transactional Database insert for a message received over HTTP. Then we will suspend this JTA transaction, and send the message to a backend service again over HTTP. On receipt of a response, we will evaluate if the result indicates a successful response, and then resume and commit the suspended transaction. On an error response, the suspended transaction is resumed, and rolled back.

Sample Configuration

As the UltraESB is written on top of the Spring Framework, it utilizes and taps into the powerful Spring framework support for transactions. In the example below, note how we use a SimpleJdbcTemplate to perform a transactional INSERT into the database. During the response mediation, we check if the last stock price equals 0 - which we assume indicates an error in this example. Subsequently, a rollback is performed on the transaction tied to the message. Note that a transactional message propagates its transactional context to any JTA aware resources during processing.

 1<u:proxy id="txn-proxy">
 2    <u:transport id="http-8280"/>
 3    <u:target>
 4        <u:inSequence>
 5            <u:java import="org.springframework.jdbc.core.simple.*;"><![CDATA[
 6                String symbol = mediation.getXMLSupport().extractAsStringUsingXPath(msg, "//request/symbol", null);
 7                msg.beginTransaction();
 8
 9                SimpleJdbcTemplate t = new SimpleJdbcTemplate(mediation.getDataSource("dataSource"));
10                t.update("INSERT INTO quotes (symbol) VALUES (?)", new Object[] {symbol});
11
12                msg.suspendTransaction();
13                System.out.println("Suspended...");
14            ]]></u:java>
15        </u:inSequence>
16        <u:inDestination>
17            <u:address>http://localhost:9000/service/SimpleStockQuoteService</u:address>
18        </u:inDestination>
19        <u:outSequence>
20            <u:java><![CDATA[
21                if (Double.parseDouble(mediation.getXMLSupport().extractAsStringUsingXPath(msg, "//last", null)) == 0) {
22                    msg.resumeAndRollbackTransaction();
23                    System.out.println("Rollback...");
24                } else {
25                    msg.resumeAndCommitTransaction();
26                    System.out.println("Commit...");
27                }
28            ]]></u:java>
29        </u:outSequence>
30        <u:outDestination>
31            <u:address type="response"/>
32        </u:outDestination>
33    </u:target>
34</u:proxy>
35
36<!--Standard Spring transactional DataSource definition-->
37<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
38    <property name="dataSource" ref="dataSource"/>
39</bean>
40
41<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
42    <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
43    <property name="url" value="jdbc:derby://localhost:1529/build/unittestdb"/>
44</bean>

To run the example, start the UltraESB sample configuration 105 as follows

asankha@asankha:~/java/ultraesb-1.7.0/bin$ ./ultraesb.sh -sample 105

Now start the sample Jetty server and the HTTP/S client through the ToolBox. For this example, we will use the Apache Derby database. To start Derby, go to the Derby bin directory and execute the following commands.

asankha@asankha:~$ cd /opt/jdk/db/bin
asankha@asankha:/opt/jdk/db/bin$ ./startNetworkServer -h localhost -p 1529
Security manager installed using the Basic server security policy.
Apache Derby Network Server - 10.4.2.0 - (689064) started and ready to accept connections on port 1529 at 2010-01-21 17:56:53.946 GMT

Once Derby starts, execute the interactive JDBC shell "ij" as follows, and create a table 'quotes'

asankha@asankha:/opt/derby-10.4.2.0/bin$ ./ij
ij version 10.4
ij> connect 'jdbc:derby://localhost:1529/build/unittestdb;create=true';
ij> CREATE TABLE quotes (symbol VARCHAR(10));
5.0 rows inserted/updated/deleted

Now issue a Preset "1" request from the ToolBox HTTP/S client to the Proxy service at URL http://localhost:8280/service/txn-proxy. For a request for Symbol "ADRT" etc, you will receive a successful response, and see the following messages on the console

Suspended...
Commit..

From "ij" you could verify the insert as follows:

ij> select * from quotes;
SYMBOL
----------
ADRT
1 row selected

Now, from the ToolBox HTTP/S client, change the request symbol from the default "ADRT" to "FAIL". This will result in the backend service returning a zero as the last sales price - on which condition, we would like to rollback the transaction. On the console, you will now see the following messages, and the "Select * from quotes" will not show the symbol, for which the request failed and was rolled back.

In this topic
In this topic
Contact Us