10.2. Seam managed transactions

EJB session beans feature declarative transaction management. The EJB container can start a transaction transparently when the bean is invoked, and end it when the invocation ends. If we write a session bean method that acts as a JSF action listener, all work associated with that action can be performed as one transaction, and committed or rolled back when the action is completely processed. This is a useful feature, and for some Seam applications, this is all that is required.
However, there is a problem with this approach: in a request from a single method call to a session bean, a Seam application may not perform all data access.
  • when the request requires processing by several loosely-coupled components, with each component being called independently from the web layer. It is common to see multiple calls per request from the web layer to EJB components in Seam.
  • when view rendering requires lazily-fetched associations.
The more transactions that exist per request, the more likely we are to encounter atomicity and isolation problems while our application processes many concurrent requests. All write operations should occur in the same transaction.
To work around this problem, Hibernate users developed the open session in view pattern. This is also important because some frameworks (Spring, for example) use transaction-scoped persistence contexts, which caused LazyInitializationExceptions when unfetched associations were accessed.
Open session in view is usually implemented as a single transaction that spans the entire request. The most serious problem with this implementation is that we cannot be certain that a transaction is successful until we commit it — but when the transaction commits, the view is fully rendered, and the rendered response may already be synchronized the client, so there is no way to notify the user that their transaction did not succeed.
Seam solves the problems with transaction isolation and association fetching, while working around the major flaw in open session in view, with two changes:
  • Seam uses an extended persistence context that is scoped to the conversation instead of the transaction.
  • Seam uses two transactions per request. The first spans from the beginning of the restore view phase until the end of the invoke application phase; the second spans the length of the render response phase. (In some applications, the first phase will begin later, at the beginning of the apply request values phase.)
The next section takes you through the setup of a conversation-scoped persistence context. Before this, we will enable Seam transaction management. You can use conversation-scoped persistence contexts without Seam transaction management, and Seam transaction management is useful even without Seam-managed persistence contexts, but they work most effectively together.

10.2.1. Disabling Seam-managed transactions

Seam transaction management is enabled by default for all JSF requests, but can be disabled in components.xml:
<core:init transaction-management-enabled="false"/>

<transaction:no-transaction />