Faces 3.1.0 - TransactionPhaseListener Issue
mbell697 Mar 22, 2012 3:54 PMI've run into a bit of an issue with the TransactionPhaseListener in faces 3.1.0, not sure if this is a bug with Face (feels like it) or something else (perhaps primefaces).
Setup:
WELD 1.1.5
JSF 2 (mojarra 2.1.7)
Primefaces 3.1.1
Seam 3.1.0 FInal (security, peristence, transaction, faces, jms)
Hibernate 4.1.1
running on Tomcat 7.0.25
I have disabled the servlet listener from seam transaction, we use explicit demarcation in the service layer.
However I am using the TransactionPhaseListener from faces with the goal of wrapping any lazy loaded associations in a transaction.
The SMPC is ConversationScoped, most backing beans are ViewScoped and with a fairly large amount of ajax calls that lazy load data association conversations are often long running and bound to the lifecycle of the ViewScoped backing bean.
The Issue:
It appears that the TransactionPhaseListener leaves transactions open on certain types of requests, most notibly it appears to be ajax requests that don't trigger a render during the render response phase (I think).
With debug logging enabled looking at a normal request I see what I would expect, something like this:
15:32:43.490 DEBUG [http-apr-8080-exec-4] org.jboss.seam.faces.transaction.TransactionPhaseListener beginning transaction prior to phase: RENDER_RESPONSE 6
15:32:43.491 DEBUG [http-apr-8080-exec-4] org.jboss.seam.transaction.EntityTransaction beginning JPA resource-local transaction
15:32:43.507 DEBUG [http-apr-8080-exec-4] org.jboss.seam.transaction.EntityTransaction registering synchronization: org.jboss.seam.persistence.ManagedPersistenceContextProxyHandler@742f8ad4
15:32:43.777 DEBUG [http-apr-8080-exec-4] org.jboss.seam.faces.transaction.TransactionPhaseListener committing transaction after phase: RENDER_RESPONSE 6
15:32:43.777 DEBUG [http-apr-8080-exec-4] org.jboss.seam.transaction.EntityTransaction committing JPA resource-local transaction
However with some ajax calls I get the following:
15:33:57.982 DEBUG [http-apr-8080-exec-8] org.jboss.seam.faces.transaction.TransactionPhaseListener beginning transaction prior to phase: RENDER_RESPONSE 6
15:33:57.982 DEBUG [http-apr-8080-exec-8] org.jboss.seam.transaction.EntityTransaction beginning JPA resource-local transaction
15:33:57.987 DEBUG [http-apr-8080-exec-8] org.jboss.seam.transaction.EntityTransaction registering synchronization: org.jboss.seam.persistence.ManagedPersistenceContextProxyHandler@742f8ad4
Upon the next request I then get:
15:34:34.463 DEBUG [http-apr-8080-exec-4] org.jboss.seam.faces.transaction.TransactionPhaseListener committing transaction after phase: INVOKE_APPLICATION 5
15:34:34.464 DEBUG [http-apr-8080-exec-4] org.jboss.seam.transaction.EntityTransaction committing JPA resource-local transaction
**snip, opens another transaction in render response phase***
It appears that a transaction is started prior to the RENDER_RESPONSE phase but never commited, well, until the next request. This appears to be creating various issues for us.
From tracing this I think the issue is in this bit of code from the TransactionPhaseListener:
public void handleTransactionsAfterPhase(final PhaseEvent event) {
PhaseId phaseId = event.getPhaseId();
if (seamManagedTransactionStatus(phaseId)) {
boolean commitTran = (phaseId == PhaseId.INVOKE_APPLICATION) || event.getFacesContext().getRenderResponse()
|| event.getFacesContext().getResponseComplete();
if (commitTran) {
commitOrRollback(phaseId); // we commit before destroying contexts,
// cos the contexts have the PC in them
}
}
}
Notibly the expression for the commitTran boolean returns false on these requests, leaving the transaction open.
As for what types of requests trigger this, it appears to be almost any ajax request made via primefaces, too many examples to list fully but ajax onchange listeners of all types, changing tabs in a tab view, data table row expansion, etc all appear to trigger this.
Anyone have thoughts on this being a bug or maybe I'm not configuring something correctly?
Cheers!