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.

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"

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.