Red Hat Training

A Red Hat training course is available for Red Hat Fuse

Chapter 8. JDBC XA Transaction Integration

Abstract

In order to integrate a database with the XA transaction manager, you need two things: an XA data source (provided by the database implementation); and a proxy data source that wraps the original XA data source and supports auto-enlistment of the XA resource (provided either by the database implementation or by a third-party library). In this chapter, the JDBC integration steps are illustrated using the Apache Derby database.

8.1. Configuring an XA Data Source

Overview

A JDBC client can access an XA data source either directly, through the javax.sql.XADataSource interface, or indirectly, through a proxy object that implements the javax.sql.DataSource interface. In the context of OSGi, the usual way to integrate an XA data source is to instantiate the data source implementation provided by the underlying database and then to export that data source as an OSGi service.

javax.sql.DataSource interface

The javax.sql.DataSource interface is the preferred way to expose a JDBC interface. It is a highly abstracted interface, exposing only two methods, getConnection and setConnection, to the JDBC client.
According to the JDBC specification, the usual way to make a DataSource object available to a JDBC client is through the JNDI registry.

javax.sql.XADataSource interface

In the context of XA transactions, a JDBC data source can be exposed as a javax.sql.XADataSource object. The main difference between an XADataSource object and a plain DataSource object is that the XADataSource object returns a javax.sql.XAConnection object, which you can use to access and enlist an XAResource object.
By default, enlisting an XAResource object is a manual procedure. That is, when using an XADataSource directly, a JDBC client must explicitly write the code to obtain the XAResource and enlist it with the current transaction. An alternative approach is to wrap the XA data source in a proxy data source that performs enlistment automatically (for example, see Section 8.2, “Apache Aries Auto-Enlisting XA Wrapper”).

Standard JDBC data source properties

The JDBC specification mandates that a data source implementation class implements the bean properties shown in Table 8.1, “Standard DataSource Properties”. These properties are not defined on the javax.sql.DataSource interface and need not all be implemented. The only required property is description.

Table 8.1. Standard DataSource Properties

PropertyTypeDescription
databaseName String (Optional) Name of the database instance.
dataSourceName String (Optional) For an XA data source or a pooled data source, names the underlying data source object.
description String (Required) Description of the data source.
networkProtocol String (Optional) Network protocol used to communicate with the database server.
password String (Optional) If required, the user and password properties can be provided to open a secure connection to the database server.
portNumber int (Optional) TCP port number where the database server is listening.
roleName String (Optional) The initial SQL role name.
serverName String (Optional) The database server name.
user String (Optional) If required, the user and password properties can be provided to open a secure connection to the database server.
Note
Although the properties shown in this table are standardized, they are not compulsory. A given data source implementation might define some or all of the standard properties, and is also free to define additional properties not mentioned in the specification.

Apache Derby

Apache Derby is an open source database implementation, which provides a full implementation of XA transactions. In the current document, we use it as the basis for some of our examples and tutorials.
Important
Apache Derby is neither maintained nor supported by Red Hat. No guarantees are given with respect to the robustness or correctness of its XA implementation. It is used here solely for the purposes of illustration.

Derby data sources

Apache Derby provides the following alternative data source implementations (from the org.apache.derby.jdbc package):
EmbeddedDataSource
A non-XA data source, which connects to the embedded Derby database instance identified by the databaseName property. If the embedded database instance is not yet running, it is automatically started in the current JVM.
EmbeddedXADataSource
An XA data source, which connects to the embedded Derby database instance identified by the databaseName property. If the embedded database instance is not yet running, it is automatically started in the current JVM.
EmbeddedConnectionPoolDataSource
A non-XA data source with connection pooling logic, which connects to the embedded Derby database instance identified by the databaseName property. If the embedded database instance is not yet running, it is automatically started in the current JVM.
ClientDataSource
A non-XA data source, which connects to the remote Derby database instance identified by the databaseName property.
ClientXADataSource
An XA data source, which connects to the remote Derby database instance identified by the databaseName property.
ClientConnectionPoolDataSource
A non-XA data source with connection pooling logic, which connects to the remote Derby database instance identified by the databaseName property.
Note
If you need to access to the additional API methods defined in the JDBC 4.0 specification (such as isWrapperFor), use the variants of these data source classes with 40 appended. For example, EmbeddedDataSource40, EmbeddedXADataSource40, and so on.

Derby data source properties

Table 8.2, “Derby DataSource Properties” shows the properties supported by the Derby data sources. For basic applications, the databaseName property (which specifies the database instance name) is the most important one.

Table 8.2. Derby DataSource Properties

PropertyTypeDescription
connectionAttributes String (Optional) Used to specify Derby-specific connection attributes.
createDatabase String (Optional) When specified with the value, create, the database instance specified by databaseName is automatically created (if it does not already exist) the next time the getConnection method of the data source is called
databaseName String (Optional) Name of the Derby database instance.
dataSourceName String (Optional) For an XA data source or a pooled data source, names the underlying data source object. Not used by the Derby data source implementation.
description String (Required) Description of the data source.
shutdownDatabase String (Optional) When specified with the value, shutdown, shuts down the database instance the next time the getConnection method of the data source is called.

Data sources as OSGi services

The JDBC specification recommends that data source objects are provided through the JNDI registry. In the context of the OSGi container, however, the natural mechanism for enabling loose coupling of services is the OSGi service registry. For this reason, the examples here show you how to create an XA data source and expose it as an OSGi service.
Note
Additionally, exposing a data source as an OSGi service has the advantage that it integrates automatically with the Aries XA data source wrapper layer. See Section 8.2, “Apache Aries Auto-Enlisting XA Wrapper”.

Blueprint

In blueprint XML, you can expose a Derby XA data source as an OSGi service using the code shown in Example 8.1, “Exposing XA DataSource as an OSGi Service in Blueprint XML”.

Example 8.1. Exposing XA DataSource as an OSGi Service in Blueprint XML

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            default-activation="lazy">
  
  <bean id="derbyXADataSource" class="org.apache.derby.jdbc.EmbeddedXADataSource">
    <property name="databaseName" value="txXaTutorial"/>
  </bean>

  <service ref="derbyXADataSource" interface="javax.sql.XADataSource">
   <service-properties>
     <!-- A unique ID for this XA resource. Required to enable XA recovery. -->
     <entry key="aries.xa.name" value="derbyDS"/>
     <entry key="osgi.jndi.service.name" value="jdbc/derbyXADB"/>
     <entry key="datasource.name" value="derbyXADB"/>
   </service-properties>
  </service>
  
</blueprint>

References

For more information about defining Derby data sources, see the Apache Derby manuals.