I have a DBManager singleton that ensures instantiation of a single EntityManagerFactory. I’m debating on the use of single or multiple EntityManager though, because a only single transaction is associated with an EntityManager.
I need to use multiple transactions. JPA doesn’t support nested transactions.
So my question is: In most of your normal applications that use transactions in a single db environment, do you use a single EntityManager at all? So far I have been using multiple EntityManagers but would like to see if creating a single one could do the trick and also speed up a bit.
So I found the below helpful: Hope it helps someone else too.
http://en.wikibooks.org/wiki/Java_Persistence/Transactions#Nested_Transactions
Technically in JPA the EntityManager is in a transaction from the
point it is created. So begin is somewhat redundant. Until begin is
called, certain operations such as persist, merge, remove cannot be
called. Queries can still be performed, and objects that were queried
can be changed, although this is somewhat unspecified what will happen
to these changes in the JPA spec, normally they will be committed,
however it is best to call begin before making any changes to your
objects. Normally it is best to create a new EntityManager for each
transaction to avoid have stale objects remaining in the persistence
context, and to allow previously managed objects to garbage collect.After a successful commit the EntityManager can continue to be used,
and all of the managed objects remain managed. However it is normally
best to close or clear the EntityManager to allow garbage collection
and avoid stale data. If the commit fails, then the managed objects
are considered detached, and the EntityManager is cleared. This means
that commit failures cannot be caught and retried, if a failure
occurs, the entire transaction must be performed again. The previously
managed object may also be left in an inconsistent state, meaning some
of the objects locking version may have been incremented. Commit will
also fail if the transaction has been marked for rollback. This can
occur either explicitly by calling setRollbackOnly or is required to
be set if any query or find operation fails. This can be an issue, as
some queries may fail, but may not be desired to cause the entire
transaction to be rolled back.The rollback operation will rollback the database transaction only.
The managed objects in the persistence context will become detached
and the EntityManager is cleared. This means any object previously
read, should no longer be used, and is no longer part of the
persistence context. The changes made to the objects will be left as
is, the object changes will not be reverted.
EntityManagers by definition are not thread safe. So unless your application is single threaded, using a single EM is probably not the way to go.