AdroitLogic Private Ltd.

  • Increase font size
  • Default font size
  • Decrease font size

Using JTA Transactions with a SOAP, REST or any other Proxy Service

This article describes the simple - yet powerful support for JTA transactions, within the UltraESB. The UltraESB transports are capable of reading a message within a resource local (e.g. JMS local) or JTA 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 article gives an example.

The UltraESB is capable of reading messages from transactional resources, as well as on initiating transactions for non-transactional reads. 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 the response, we will evaluate if the result is a successful response, and then resume and commit the suspended transaction. On an error response, the suspended transaction is resumed, and rolled back.

As the UltraESB is written on top of the Spring Framework, it utilizes the powerful Spring support for transactions. In addition, this allows mediation to be specified in the developer friendly Spring format. 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 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.

    <u:proxy id="txn-proxy">
<u:transport id="http-8280"/>
<u:target>
<u:inSequence>
<u:java import="org.springframework.jdbc.core.simple.*;"><![CDATA[
String symbol = Mediation.extractAsStringUsingXPath(msg, "//request/symbol", null);
msg.beginTransaction();

SimpleJdbcTemplate t = new SimpleJdbcTemplate(Mediation.getDataSource("dataSource"));
t.update("INSERT INTO quotes (symbol) VALUES (?)", new Object[] {symbol});

msg.suspendTransaction();
System.out.println("Suspended...");
]]></u:java>
</u:inSequence>
<u:inDestination>
<u:address>http://localhost:9000/service/SimpleStockQuoteService</u:address>
</u:inDestination>
<u:outSequence>
<u:java><![CDATA[
if (Double.parseDouble(Mediation.extractAsStringUsingXPath(msg, "//last", null)) == 0) {
msg.resumeAndRollbackTransaction();
System.out.println("Rollback...");
} else {
msg.resumeAndCommitTransaction();
System.out.println("Commit...");
}
]]></u:java>
</u:outSequence>
<u:outDestination>
<u:address type="response"/>
</u:outDestination>
</u:target>
</u:proxy>

 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="url" value="jdbc:derby://localhost:1529/build/unittestdb"/>
</bean>

To run the example, start the UltraESB sample configuration 105 via the ToolBox or on the command line as follows

asankha@asankha:~/java/ultraesb-1.0-beta-1/bin$ ./ultraesb.sh -sample 105

Now start the sample Jetty server and the HTTP/S client through the ToolBox. For this example, you could use the Apache Derby database - or use any other database, by placing your JDBC Jar file into the lib directory of the UltraESB, and by editing the Spring configuration for the datasource as necessary.

To start Derby, go to the Derby bin directory and execute the following commands. For this example, we have used a Derby 10.4.2.0 installation, and start the server on localhost over port 1529

asankha@asankha:~$ cd /opt/derby-10.4.2.0/bin
asankha@asankha:/opt/derby-10.4.2.0/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));
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.