HomeAbout MeContact
Java
Java Transaction API + EJB
Piotr Szarpak
Piotr Szarpak
April 10, 2020
2 min
Make sure to subscribe to our newsletter and be the first to know the news.

Java Transaction API (JTA) + EJB

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.

Getting UserTransaction

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:

@Resource
UserTransaction userTransaction;

Getting EJBContext

Obtaining EJBContext interface instance can be done at least in five ways:

  • field injection:
@Resource
private SessionContext sctx;
  • setter injection:
private SessionContext sctx;
@Resource
private void setSessionContext(SessionContext sctx) {
this.sctx = sctx;
}
  • Look up the injected resource based on the name filed of @Resource annotation:
@Resource(name = "sessionContext")
private SessionContext sctx;
public void method() {
try {
InitialContext ic = new InitialContext();
} catch (NamingException ex) {
throw new IllegalStateException(ex);
}
}
  • Using default name if the name field of @Resource annotation is not specified. Note that the default name of the injected resource is: fully-qualified-class-name/variable-name:
@Resource
private 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);
}
}
  • Look-up by the standard name 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 vs CMT

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 transaction
ut.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 operations
ut.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 operations
ut.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:

@Stateless
public MyBean{
@PersistenceContext
private EntityManager em;
public void method(){
//conteiner starts transaction
// do some em operations
// method ends, conteiner commits transaction
}
}

JTA + DataSource

In JTA it is possible to execute direct database queries by using java.sql.DataSource interface:

@Stateful
@TransactionManagement(TransactionManagementType.BEAN)
public class BeanEJB {
@Resource
private SessionContext ctx; // EJBContext
methodA() {
Statement stmt;
UserTransaction ut = ctx.getUserTransaction();
// start a transaction
ut.begin();
ds = (javax.sql.DataSource)
initCtx.lookup("java:comp/env/jdbc/myDataSource");
con = ds.getConnection();
stmt = con.createStatement();
stmt.executeUpdate(...); // make some updates on con
stmt.close();
con.close();
ut.commit();
}
}

Conclusion

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.


Tags

Share

Piotr Szarpak

Piotr Szarpak

Java passionate

Sed commodo, est quis maximus fermentum, massa ipsum euismod neque, in varius risus tellus quis lacus. Sed ac bibendum odio.

Expertise

Java > 11
DDD
Spring
Databases

Social Media

githubtwitterwebsite

Related Posts

Equals and HashCode methods in Java
Equals and HashCode methods in Java
April 10, 2020
3 min
© 2024, All Rights Reserved.
Powered By

Quick Links

Advertise with usAbout UsContact Us

Social Media