Chapter 8. JDBC XA Transaction Integration
Abstract
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). Because the proxy data source also supports connection pooling, there is no need to wrap the original data source in a pooled driver, such as commons-dbcp or tomcat-jdbc.
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
.
Property | Type | Description |
---|---|---|
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) IP 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.
Property | Type | Description |
---|---|---|
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.