views:

504

answers:

1

Hello,

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.

+4  A: 

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. With CMT, 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).

ewernli
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.
Pascal Thivent
@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.
ewernli
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!
Pascal Thivent
@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.
ewernli