A JPA application can run in non-managed ( standalone, simple Web- or Swing applications) and managed Java EE environments. In a non-managed environment, an EntityManagerFactory is usually responsible for its own database connection pool.
The application developer has to manually set transaction boundaries, in other words, begin, commit, or rollback database transactions itself. A managed environment usually provides container-managed transactions, with the transaction assembly defined declaratively through annotations of EJB session beans, for example. Programmatic transaction demarcation is then no longer necessary, even flushing the EntityManager is done automatically.
Usually, ending a unit of work involves four distinct phases:
1. commit the (resource-local or JTA) transaction (this automatically flushes the entity manager and persistence context)
2. close the entity manager (if using an application-managed entity manager) handle exceptions
3. We'll now have a closer look at transaction demarcation and exception handling in both managed- and non-managed environments.
Database (or system) transaction boundaries are always necessary. No communication with the database can occur outside of a database transaction (this seems to confuse many developers who are used to the auto-commit mode). Always use clear transaction boundaries, even for read-only operations. Depending on your isolation level and database capabilities this might not be required but there is no downside if you always demarcate transactions explicitly. You'll have to do operations outside a transaction, though, when you'll need to retain modifications in an EXTENDED persistence context.