There are situations despite how much database tuning effort you put into a project, there might be complex queries or a batch process initiated via a Servlet, which might take several minutes to execute. The issue is that if you call a long query from a Servlet or JSP, the browser may time out before the call completes. When this happens, the user will not see the results of their request. There are proprietary solutions to this problem like asynchronous servlets in WebLogic, Async Beans in WebSphere etc but you need a solution that is portable. Let us look at portable solutions to this issue.
Solution 1: Client-pull or client-refresh (aka server polling): You can use the
<META> tag for polling the server. This tag tells the client it must refresh the page after a number of seconds.
<META http-equiv=”Refresh” content=”10; url=”newPage.html” />
Once you can have the browser poll your Servlet on a regular basis to re-fetch a page, then your servlet can check for a value of a variable say in a
HttpSession to determine if the page returned will have the results expected by the user or resend the
<META> tag with a “Please wait …” message and retry fetching the page again later.
Solution 2: J2EE Solution: Instead of spawning your own Threads within your Servlet, you could use
JMS (Java Messaging Service). This involves the following steps:
- You need to have two servlets, a
DisplayingServlet. The initial client request is sent to the
RequestingServlet. Both the
DisplayingServletpolled by the browser via
<META>tag with their responses until the final display of the query results.
RequestingServletplaces the query on the “
request” queue using
- You need to have a
MessageDrivenBean(aka MDB) say
QueryProcessorMDB, which dequeues the query from the “request” queue and performs the long-running database operation. On completion of processing long-running database operation, the
QueryProcessorMDBreturns the query results to the “reply” queue (use
javax.jms.ObjectMessage). Note: MDBs are invoked asynchronously on the arrival of messages in the queue.
DisplayingServletchecks the “reply” queue for the query results using JMS (use
javax.jms.ObjectMessage) every few seconds via
Advantages: Firstly implementing your long-running database operation to be invoked from onMessage()method of your QueryProcessorMDB decouples your application whereby if a database failure occurs, the request query message will be placed back in the “request” queue and retried again later. Secondly, MDBs can be clustered (with or without additional JVMs) to listen on the same “request” queue. This means a cluster of MDBs will be balancing the load of processing long-running database operations. This can improve throughput due to increased processing power.