What is difference between @Resource UserTransaction and EntityManager.getTransaction()
Asked Answered
M

3

31

Can anybody explain what is difference between :

@Resource
UserTransaction objUserTransaction;

and

EntityManager.getTransaction();

And also what is container managed transaction? and how should I do it in my session facade if I want to insert three rows in table in transaction.

Mechanist answered 25/3, 2010 at 15:52 Comment(1)
A good article to get a better idea about EJB Transactions, IMO, a must read entjavastuff.blogspot.com/2011/02/…Effector
D
31

EJB are transactional components. The transaction can be managed either by the applicaiton server itself (CMT - container-managed transaction), or manually by yourself within the EJB (BMT - bean-managed transaction).

EJB supports distributed transaction through the JTA specification. The distributed transaction is controlled using UserTransaction, which has methods begin, commit, rollback.

With CMT, the application server starts, commit and rollback the transaction (according to the transaction annotations) for you and you are not allowed to interfere. This means you must not access the UserTransaction in this case. However, with BMT, you do that manually and you control the transaction yourself using the UserTransaction.

Let's move now to the EntityManager. A JPA implementation can be used either within an application server or stand-alone. If use in stand-alone, you need to use EntityManage.getTransaction to demarcate the JDBC transaction yourself. If used within an application server, the EntityManager cooperated with the JTA distributed transaction manager transparently for you.

Most of the time, you use CMT with @Required annotation on the EJB. This means that you don't need to access neither UserTransaction nor EntityManager.getTransaction. The app. server starts and commits the transaction, but also takes care to rollback if an exception is raised. This is what I would recommend for your facade.

(There are more subtleties, such as the PersistenceContextType or the manual enlistment of the entity manager in distributed transaction with EntityManager.joinTransaction, but that's only if you use the technologies in a different ways as the default).

Discontinuation answered 25/3, 2010 at 17:4 Comment(4)
Are you sure that EntityManager#getTransaction() cooperates with the JTA distributed transaction when running inside an app server? I don't think it does, my understanding is that it returns a resource-local transaction that can be used to persist data outside of the current JTA transaction.Holmium
@Pascal The EntityManager cooperates with JTA so you shouldn't use EntityManager#getTransaction at all. As per the javadoc, EntityManager#getTransaction throws IllegalStateException if invoked on a JTA EntityManager.Discontinuation
Indeed, getTransaction throws an exception when invoked on a JTA EntityManager). Actually, the example I had in mind (from "Pro JPA 2") is to get an application managed, resource-local EM in a Session Bean - e.g. for audit logging - and a resource local transaction that you can begin/commit as many time as you want outside the JTA transaction. But I realize that I misread your answer, this is different from what you wrote. Thanks!Holmium
@Pascal For audit, we used CMT with REQUIRE_NEW for the audit methods. That's the only way AFAIK to pause and resume the current transaction with CMT.Discontinuation
R
9

UserTransaction refers to the JTA transaction entity. You will only be able to use this when there is a JTA module available in the application server: for example, if you're deploying an application with this on Tomcat (which by default does not support JTA), code relying on this will fail. This is default type of transaction used in EJB's and MDB's.

EntityManager.getTransaction() retrieves a local transaction entity. This also sometimes known as a resource local transaction.

Resource local transactions are very different from JTA transactions: among other things, resource local transactions are specific to a resource, whereas JTA transactions tend to be specific to a particular thread.

For more information on the difference between resource local and JTA transactions, see this stackoverflow answer here: What is the difference between a JTA and a local transaction?

Representational answered 25/10, 2013 at 15:19 Comment(0)
R
0

In addition to @Marco's answer which does well to tell the difference between the JTA and resource local transactions.

Container Managed Transactions are [as it is named] managed by the container rather than your application. This is done through the EJB tier where you just need to write your method and the container will wrap the method around a transaction context so if any part of your method or its lower level calls throws an exception, the transaction will rollback.

It can also be fine tuned using annotations. More info can be found here https://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

Note that this is only done through EJBs, and entity managers that are injected on the web tier (e.g. servlets or REST API) do not get managed by the container in which case you have to look up the transaction using @Resource UserTransaction or EntityManager.getTransaction, begin() and commit() yourself.

From Java EE 6 you are allowed to have EJBs inside the web tier so you don't need to have an overly complex project layout unless you start wanting to expose your EJBs as web services.

Rms answered 22/11, 2014 at 12:52 Comment(2)
In EE container managed transactions are available outside EJB via the "@Transactional" annotation.Sauceda
JTA transactions are not necessarily CMT, since JTA can be used outside of application servers (or "containers") with libraries such as Bitronix and Atomikos.Representational

© 2022 - 2024 — McMap. All rights reserved.