I\'ve recently started working with JPA on the Google App Engine. In reading some examples, I\'ve noticed a couple of variations in the way objects are persisted. In one cas
You'd use getTransaction()
when you're explicitly handling the transactions in your application. On the other hand, if you let the container handle the transactions for you, it won't be necessary to explicitly begin/end transactions. Essentially, we're dealing with the difference between Container Managed Transactions (CMT) and Bean Managed Transactions (BMT).
In general, you'd use BMT when you need more control over the transactional processing, or when there are additional technical requirements (for instance, two-phase commits, distributed transactions, XA transactions) that can't be met by using CMT. Also, you'd use BMT when your applications is deployed outside of an application server and relies on Java SE.
Google App Engine has its transaction management (https://developers.google.com/appengine/docs/java/datastore/transactions) but the JPA transaction interface isn't aware of some of the GAE underlying functionalities (i.e. entity groups).
So it’s up to your application to decide which operations to perform in a transaction and which not. You should put in a transaction operations that have to be executed atomically.
Remember as a best practice to perform cascading actions and relationship operations in a transaction because JPA might trigger many queries and it could lead to an inconsistent data situation.
Example of using transaction with JPA2:
import javax.persistence.EntityTransaction;
EntityTransaction txn = em.getTransaction();
txn.begin();
try {
//do something with your database
txn.commit();
}
finally {
if (txn.isActive())
txn.rollback();
}
If you use container managed EntityManager
then you're using JTA transactions. Hence, you don't need to (more precisely - you can not) interfere with EntityManager
's transactions fetched using entityManager.getTransaction()
. The JTA starts and commits your transaction.
If you use application managed EntityManager
and you don't want to be in part of JTA transaction, then you need to manage them for yourself (it's called a resource-local entity manager).
Most typically, application managed EntityManager
which works with EntityManager.getTransaction()
is used in Java SE environment.
EDIT: You might be interested in secion 7.5 Controlling Transactions from the JPA 2.0 specification.
In GAE there is no Java EE/JTA so ignore terms such as bean managed transaction (BMT), and container managed transactions (CMT).
Your work is either transactional (where you want multiple objects to go to the datastore at once, or all to fail - this is where you have getTransaction() used), or nontransactional (where everything goes to the datastore one by one, and the failure of one persist doesn't affect others - this is where you just call persist()/merge()/remove()).