LibraryLink ToToggle FramesPrintFeedback

Transaction Architecture

Figure 1.2 shows an overview of the OSGi transaction architecture in Fuse ESB. The core of the architecture is a JTA transaction manager based on Apache Geronimo, which exposes various transaction interfaces as OSGi services.


The JTA Transaction Services Specification section of the OSGi Service Platform Enterprise Specification describes the kind of transaction support that can (optionally) be provided by an OSGi container. Essentially, OSGi mandates that the transaction service is accessed through the Java Transaction API (JTA).

The transaction service exports the following JTA interfaces as OSGi services (the JTA services):

Only one JTA provider should be made available in an OSGi container. In other words, the JTA services are registered only once and the objects obtained by importing references to the JTA services must be unique.

The Fuse ESB transaction service exports the following additional interfaces as OSGi services:

By obtaining a reference to the PlatformTransactionManager OSGi service, it is possible to integrate application bundles written using the Spring transaction API into the Fuse ESB transaction architecture.

Fuse ESB provides an OSGi-compliant implementation of the transaction service in the following bundle (which is installed in the OSGi container by default):

org.apache.aries.transaction.manager

The Fuse ESB transaction bundle exports exports a variety of transaction interfaces as OSGi services (making them available to other bundles in the container), as follows:

The PlatformTransactionManager OSGi service and the JTA services access the same underlying transaction manager.

The underlying implementation of the Fuse ESB transaction service is provided by the Apache Geronimo transaction manager. Apache Geronimo is a full implementation of a J2EE server and, as part of the J2EE implementation, Geronimo has developed a sophisticated transaction manager with the following features:

  • Support for enlisting multiple XA resources.

  • Support for 1-phase and 2-phase commit protocols.

  • Support for suspending and resuming transactions.

  • Support for automatic transaction recovery upon startup.

The transaction recovery feature depends on a transaction log, which records the status of all pending transactions in persistent storage.

The implementation of the transaction log is provided by HOWL, which is a high speed persistent logger that is optimized for XA transaction logs.

Normally, it is recommended that application bundles access the transaction service through the JTA interface. To use the transaction service in a JTA-based application bundle, import the relevant JTA service as an OSGi service and use the JTA service to begin, commit, or rollback transactions.

If you have already implemented an application bundle using the Spring transaction API, you might find it more convenient to access the transaction service through the Spring API (represented by the PlatformTransactionManager Java interface). This means that you are able to deploy the same source code either in a pure Spring container or in an OSGi container, by changing only the configuration snippet that obtains a reference to the transaction service.

In order to enlist multiple resources in the same transaction (where a transaction is committed through the 2-phase commit protocol), it is necessary for each participating resource to provide an XA switch. An XA switch is an object that enables the transaction manager to control a resource manager through the XA interface, javax.transaction.xa.XAResource.

The JTA provides a method for enlisting XAResource objects in the current transaction. Using this approach, it is possible to enlist multiple XA resources in the current transaction.

The standard JTA approach to enlisting XA resources is to add the XA resource to the current javax.transaction.Transaction object (representing the current transaction). In other words, you must explicitly enlist an XA resource every time a new transaction starts.

If you are familiar with how transactions work in J2EE containers, you might find this approach surprising: a J2EE container automatically enlists the relevant XA resource in the current transaction whenever you access a data source. In contrast to the J2EE approach, however, the OSGi container does not automatically enlist XA resources in the current transaction. You must write the code to enlist the XA resources yourself or implement a custom wrapper layer.

In the case of JMS XA resources, ActiveMQ provides an XA pool wrapper class that implements auto-enlistment for you. Use the following JMS connection factory class:

[Note]Note

If you are using a JMS implementation other than ActiveMQ, you could use the XA pool connection factory from the Jencks project, org.jencks.pool.PooledSpringXAConnectionFactory. This connection factory is suitable for generic JMS implementations.

ActiveMQ supports the standard JMS framework for managing transactions. The approach to managing transactions in JMS depends on whether you use local transactions (where the broker is the only participating resource) or global transactions (where multiple resources participate in the transaction), as follows:

Through the ActiveMQXAConnectionFactory JMS connection factory, ActiveMQ can provide an XA resource that represents the underlying message broker. This means that messages will not be added to or removed from the broker's persistent storage, unless the current transaction completes successfully. The following broker persistence layers provide full support for the XA protocol (including a persistent transaction log that enables recovery):

To obtain a reference to the ActiveMQ XA resource, you must use the ActiveMQXAConnectionFactory JMS connection factory to access the broker.

Apache Camel provides a Camel JMS component, which is capable of integrating with the JTA transaction service with full support for XA transactions. In order to support XA transactions, you must configure the Camel JMS component's JMS connection factory and transaction manager as follows:

In principle, you can replace the default transaction manager with an alternative transaction manager, but this requires you to write a significant amount of custom code. If you want to replace the Geronimo transaction manager with a different transaction manager implementation, you could do so as follows:

[Tip]Tip

For example, a suitable alternative transaction manager is Atomikos TransactionEssentials, which is another Open Source, Apache-licensed transaction manager. But this transaction manager does not currently provide its own OSGi integration layer, so you would have to implement that yourself.

The following specifications are relevant to the transaction architecture in Fuse ESB: