How to Use the Java Transaction API
Transaction processing is important for application that works with critical data handling in a business application that require of high level of reliability and consistency in data exchange such as bank transfer, e-commerce, and so forth. Transaction basically clubs multiple CRUD operations into a single logical unit of operation called transaction processing. This is a low-level routine that must perform in its entirety or not at all. It can be a daunting task for a programmer to start everything from scratch, unless, of course, a framework such as J2EE provides transaction services that take care of much of the dirty work on behalf of the programmer. The article focuses on the conceptual aspect of transaction management within the purview of Java Transaction API as groundwork for JTA implementation in a subsequent article.
Concept of Transaction
Transaction is a unit of operation to access and possibly update various data items in a business-critical module, such as transferring funds from one account to another, persisting data in one or more databases, sending message to a message-oriented middleware, invoking web services, and so on. They comprise one or more thread of operation under a single unit of execution. Transaction is crucial because data is crucial; they must be in a reliable and consistent state throughout the execution. To ensure consistency across multiple operations, transactions are processed either fully or not at all. Successful transactions are committed (persisted), whereas unsuccessful ones are rolled back (to the previous state). The user program usually encompasses multiple operations within statements of the form begin transaction and end transaction. The degree of reliability is ascertained with commit statements such as success and rolled back on failure. The integrity of the transaction must adhere to the following ACID properties:
- Atomicity: Transaction is an atomic unit of operation that is committed in its entirety or not performed at all.
- Consistency: In the process of transaction, the consistent state of the data must be preserved from one consistent state to another after complete execution.
- Isolation: The transaction must be performed in an isolated manner so that any other concurrent transaction must not interfere within the process.
- Durability: Once the transaction is committed, the changes must persist, and be available for the next set of operations.
Suppose you have purchased an item from a vendor and proceed to pay through bank transfer from your account to vendor's account. The sequence of database operation can be the following:
- Your account is debited by using an update statement.
- The vendor's account is credited by using a different update statement.
- A log is maintained to keep track of the transfer.
The operations must be completed as a single unit of work to ensure atomicity. The transaction must not be interfered by any other transaction and must complete in isolation. The transaction must ensure that the data is in a consistent in the database. It does not matter whether or not the transaction is successful. Data must be available for other uses only after completion of the transaction to ensure durability. A transaction is complete only if it results in a commit, denoting success or rollback, denoting a failure.
Figure 1: The transaction process
Java Transaction API Components
Transaction processing in Java is an interplay of multiple components. Each component plays a vital role to maintain the ACID properties of transaction. The application decides whether to commit the transaction or rollback and delegates responsibility to the underlying transaction manager which in turn prepares the resources and delegates down the line. The component trio that take part in the process is as follows:
- Transaction Manager: This is the core component to manage transactional operations. It is responsible for reciprocating the underlying resource manager about the transaction operation on behalf of the application to conduct either a commit or rollback operation.
- Resource Manager: This component manages the resources by registering them to the transaction manager. A resource manager can be a JDBC driver, JMS resource, and the like.
- Resource: This component is typically a database for data persistence from a successful read, write operation.
Figure 2: The Java transaction API components
Resources that are distributed across multiple databases require special coordination involving XA (eXtended Architecture) with Java Transaction Service (JTS). XA is a standard for Distributed Transaction Processing (DTP) specified by Open Group. JTA supports DTP and allows a heterogeneous resource manager to operate through a common interface. XA uses a 2PC (Two-Phase Commit) protocol to ensure success or failure of a transaction outcome.
Figure 3: The two-phase commit
Transaction Support in EJBs
The Java Transaction API (JTA) with EJB provides features that are quite simple to implement. The EJB backed services can handle transactions with high levels of abstraction, programmatically or by using metadata, declaratively.
In a declarative transaction, the demarcation policy is delegated to the EJB container with the help of metadata and does not require one to write explicit JTA code. Because this type of transaction is managed by the container, it is called Container Managed Transaction (CMT).
In the case of a Bean Managed Transaction (BMT), the transaction demarcations are specified programmatically. BMT is particularly useful for situations where fine tune demarcation granularity is required. Here, transaction boundaries can be managed explicitly.
Java EE7 extended CMT beyond EJBs to provide transaction support in Managed Beans with the help of interceptors and interceptor binding. As a result, transaction processing is possible with components such as Servlets or Web Services with the help of CDI interceptor binding.
JTA allows business applications to keep data in a consistent state throughout transaction operation with the help of CMT, BMT, and Managed Beans. JTS ensures that the ACID properties are met even when resources are accessed from multiple applications concurrently. Although it is easy to customize transaction demarcation in an EJB container with CMT, BMT is there to give finer control of transaction demarcation directly through JTA code. CDI binding pushed further transaction processing to another level through Managed beans.