Java Transaction API (JTA) is an API that enables you to use the X/Open XA standard in Java when working with transactions. To use JTA, we need to have a dedicated implementation of this API, where one of them is a EJB container. Usually, it is used while working with Java Persistence API (JPA), however, it is not required, as we can use it purely with JDBC API. Other popular implementations of JTA are Atomikos and Bitronix.
JTA provides javax.transaction.UserTransaction
interface for transaction management. We can obtain an instance of this interface using the getUserTransaction
method
from javax.ejb.EJBContext
interface or by injecting it with @Resource
annotation:
@ResourceUserTransaction userTransaction;
Obtaining EJBContext
interface instance can be done at least in five ways:
@Resourceprivate SessionContext sctx;
private SessionContext sctx;@Resourceprivate void setSessionContext(SessionContext sctx) {this.sctx = sctx;}
@Resource
annotation:@Resource(name = "sessionContext")private SessionContext sctx;public void method() {try {InitialContext ic = new InitialContext();} catch (NamingException ex) {throw new IllegalStateException(ex);}}
@Resource
annotation is not specified. Note that the default name of
the injected resource is: fully-qualified-class-name/variable-name:@Resourceprivate SessionContext sctx;public void method() {try {InitialContext ic = new InitialContext();SessionContext sctxLookup = (SessionContext) ic.lookup("java:comp/env/com.foo.ejb.HelloBean/sctx");} catch (NamingException ex) {throw new IllegalStateException(ex);}}
java:comp/EJBContext
:public void method() {try {InitialContext ic = new InitialContext();SessionContext sctxLookup = (SessionContext) ic.lookup("java:comp/EJBContext");} catch (NamingException ex) {throw new IllegalStateException(ex);}}
BMT (Bean-managed transaction) is a type of transaction management in JTA in which we manually manage our
transaction in EJB bean. To enable BMT we have to add @TransactionManagement
annotation
with value TransactionManagementType.BEAN
:
@Stateless@TransactionManagement(TransactionManagementType.BEAN)public class MyBean{...}
To work in BMT mode, no ORM is needed. All we have to do is to start the transaction before we do any further actions:
UserTransaction ut = ctx.getUserTransaction();// start a transactionut.begin();
What is more, when working with JPA and using application-managed javax.persistence.EntityManager, all we have to remember is to create EntityManager after we start the transaction:
UserTransaction ut = ctx.getUserTransaction();ut.begin();EntityManager em = emf.createEntityManager();// do some em operationsut.commit();
If the EntityManager had been created before the transaction was started, operations performed by EntityManager
would not run in a started transaction. To change that, we have to “join” the EntityManager to the transaction
by invoking its joinTransaction
method:
EntityManager em = emf.createEntityManager();ut.begin();em.joinTransaction(); // join the transaction// do some em operationsut.commit();
In order to have a transactions managed by the container (CMT), which is the default mode, all we have to do is to inject the EntityManager in the EJB bean and perform its operations in business methods. The transaction will be started, committed or rolled back (only for runtime exceptions) automatically by the container:
@Statelesspublic MyBean{@PersistenceContextprivate EntityManager em;public void method(){//conteiner starts transaction// do some em operations// method ends, conteiner commits transaction}}
In JTA it is possible to execute direct database queries by using java.sql.DataSource
interface:
@Stateful@TransactionManagement(TransactionManagementType.BEAN)public class BeanEJB {@Resourceprivate SessionContext ctx; // EJBContextmethodA() {Statement stmt;UserTransaction ut = ctx.getUserTransaction();// start a transactionut.begin();ds = (javax.sql.DataSource)initCtx.lookup("java:comp/env/jdbc/myDataSource");con = ds.getConnection();stmt = con.createStatement();stmt.executeUpdate(...); // make some updates on constmt.close();con.close();ut.commit();}}
JTA is a powerful API that enables us to manage transactions in Java. It is a standard API, so it can be used
in any Java EE application server. It is also possible to use it in Java SE applications, however, it requires
an application server to be installed and configured. JTA is a very useful API, especially when working with
JPA, as it enables us to manage transactions in a declarative way. It is also possible to use it with JDBC API,
however, it is not recommended, as it is much easier to use java.sql.Connection
interface to manage transactions
in JDBC.
Quick Links
Legal Stuff