org.springframework.webflow.conversation.impl.LockTimeoutException: Unable to acquire conversation lock after 30 seconds
at org.springframework.webflow.conversation.impl.JdkConcurrentConversationLock.lock(JdkConcurrentConversationLock.java:44)
at org.springframework.webflow.conversation.impl.ContainedConversation.lock(ContainedConversation.java:69)
at org.springframework.webflow.execution.repository.support.ConversationBackedFlowExecutionLock.lock(ConversationBackedFlowExecutionLock.java:51)
at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:166)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
at org.springframework.webflow.mvc.servlet.FlowController.handleRequest(FlowController.java:174)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

2 Answers
2

Spring Webflow operates as a state-machine, executing transitions between different states which might have associated views. It doesn't make sense to have multiple concurrently executing transitions, so SWF uses a locking system to make sure that each flow execution (or conversation) only handles one HTTP request at a time.

Don't get too hung up on the concept of ReentrantLock, it just prevents the same thread waiting on a lock that it already holds.

In answer to your question, it is only the flow execution (the specific conversation instance) that is locked by Spring Webflow for the duration of the request handling. The server will still handle requests from other users, or even requests from the same user to a different flow execution.

LockTimeoutException is tricky to troubleshoot because the root problem is not the thread throwing the exception. The LockTimeoutException occurs because another earlier request is taking longer than 30 seconds, so it would be a good idea to find out why the earlier request took so long.

Troubleshooting ideas:

Implement a FlowExecutionListener which measures how long each request takes, and log long requests along with the flowId, stateId and transition event, this will allow you to hone in on long-running requests.

One good way to avoid the LockTimeoutException itself is to disable submit buttons & links using javascript once a button/link has been clicked. Obviously this doesn't solve the problem of the initial 30-second+ request.

You could increase the timeout for LockTimeoutException, but that doesn't solve the actual problem and leads to a worse user-experience. 30-second requests are the problem.

Finally, you mentioned:

I have been trying to figure out why does above exception comes in
some cases when there is only a single click or we are accessing the
home page of the site itself.

I suggest that you try re-create the problem with the browser's developer tools window open, watching the 'Network' tab, maybe there is an AJAX request running in the background which is holding the lock.