Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

FAQ Category:

This problem is commonly seen in applications that use Ajax in the context of a long-running conversation. If the problem happens when a conversation is still active, it's because one of the requests could not get a lock on the conversation in the allotted time period. Many developers run into this problem for the first time when using a CRUD application created by seam-gen. This entry explains the problem using the seam-gen application as an example.

Each input field on the editor screen uses the Ajax4jsf support component to validate the user's input on blur. If the validation request is still active when another one is fired off or the user clicks one of the submit buttons, there is a contention on the server for the same conversation. Recall that Seam serializes access to the same conversation and will abort the request if it has to wait too long to get a lock on the conversation.

One solution is to ensure that the Ajax4jsf validation requests are also serialized so that they never contend for the conversation. This is done using the eventsQueue attribute:

<a:support event="onblur" rerender="nameDecoration"
  bypassUpdates="true" ajaxSingle="true"
  eventsQueue="validation"/>

For more information about eventsQueue, please see the Seam or RichFaces reference documentation.

Of course, we still have to deal with the situation where the user clicks on a non-Ajax submit button while one of the form fields has focus. In this case, the normal form submission may contend with any concurrent validation request. One way to avoid running into this issue to to increase the concurrent request timeout from the default of 1 second (in seam-gen applications, this value is set to 500 milliseconds):

<core:manager concurrent-request-timeout="2000" .../>

However, letting requests hang on the server can have an impact on performance. An even better solution is keep the concurrent request timeout short and make the submit button also use an Ajax request. Ajax4jsf is smart enough to follow the navigation rules even if the request is made using Ajax.

<a:commandButton action="#{entityHome.update}" .../>

So the lesson is that to avoid contention for a conversation on the server, you should serialize requests for the same conversation on the client as well.

Note that this problem is not often seen when using ICEFaces since the ICEfaces framework synchronizes operations during a server-initiated render call to ensure that the server-side DOM remains uncorrupted.

Note that this problem isn't seen often when using ICEFaces since the ICEfaces framework synchronizes requests from the same page to ensure that the server-side DOM remains uncorrupted.

3 comments:
 
21. Jun 2008, 19:07 America/New_York | Link

The interesting thing to note here is that a queue on the client that serializes AJAX requests effectively disables the A in AJAX. Requests are synchronized and processed FIFO, they are no longer asynchronous. That means any UI interaction that triggers a queued event then blocks the UI until the event moves to the head of the queue.

This is where the all state on the server model breaks down for AJAX. I usually work around this by mixing some jQuery code into my highly interactive forms, so I can do some of the processing on the client. Now, if all these stupid JSF components wouldn't be such awful black boxes and if JSF would allow me to mix that additional behavior easily into a custom extension of a toolkit component... this is why it is so important that JSF 2.0 has to get the custom component thing right. I'm not holding my breath though.

 

Check out my weblog or have a look at the books I wrote.

 
27. Sep 2008, 00:43 America/New_York | Link

I had the same error and it was resolved by adding id to commandButton tag

<a:commandButton id="xxx" action="#{entityHome.update}" .../>
 
30. Jan 2009, 22:36 America/New_York | Link
will using |<a4j:queue/>| on all JSF pages be a better way to handle this problem? any hints about how we should use this new |<a4j:queue/>| tag??

"The Ajax Requests area represent individual Ajax requests that can be fired by clicking the green images (<a4j:commandLink/> components). A JSF managed bean on the server causes a random sleep time (4 seconds or less) to simulate different processing times for each request. The <a4j:queue/> (defined as global for the form where controls placed) handles all the requests and fires next one only after the responce from previous returned."

[http://livedemo.exadel.com/richfaces-demo/richfaces/queue.jsf=>http://livedemo.exadel.com/richfaces-demo/richfaces/queue.jsf]
 

required reading: Scala and more Scala... www.artima.com