I am currently in a project where we have a method that is called to generate a report and then return it to the client side. The whole process works something like this:
[[Application]] --> [[JMS]] --> [[DB Server]]
However, our WebSphere has a global setting where Transaction Timeout is set to 2 minutes, and Maximum Transaction Timeout is set to 5 minutes.
This has caused us some problems because some of our reports take longer than 2 minutes, and as such, the connection is dropped at the JMS because there is no response from the DB Server after 2 minutes.
However, the query is still running in the DB Server, and after about 20 minutes when the query completes, it tries to return the result but is not able to because the connection is already dropped.
Below is the method that we are calling
public void generateReport(long ticketID, long inst_data_id, boolean flag)
throws AppException, InformationalException {
Trace.kToolsLogger.info("*********** Report generation started ******");
if(Configuration.runningInAppServer()){
try {
Trace.kToolsLogger.info("*********** Transaction timeout set to 1200 ******");
InitialContext ctx = new InitialContext();
UserTransaction tx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
tx.setTransactionTimeout(1200);
} catch (SystemException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} else{
Trace.kToolsLogger.info("Not running in app server. Timeout not set to 120");
}
However, the above setting is still not working and my method is still timing out at 2 minutes.
This is the error that I always encounter after 2 minutes:
[4/20/16 12:56:06:105 SGT] 00000122 TimeoutManage I WTRN0006W: Transaction Curam#coreinf-ejb.jar#DPEnactmentMDB 000001543204A61800000001478C576857C2F09B4365FB74A6A3A28FED806D44107D7CBC000001543204A61800000001478C576857C2F09B4365FB74A6A3A28FED806D44107D7CBC00000001 has timed out after 120 seconds. [4/20/16 12:56:06:108 SGT] 00000122 TimeoutManage I WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was Thread[SIBJMSRAThreadPool : 1,5,main]. The stack trace of this thread when the timeout occurred was:
We have investigated and know that we can configure another JMS. But how will we be able to call out that particular JMS from the method? Also, is there any other way to overwrite the Transaction Timeout in Websphere?
Appreciate any kind of response. Thank you. Please let me know if you require any other information.
EDIT: I am aware of being able to update the Transaction Timeout at WebSphere level, but we are hoping to leave it at 2 minutes as we just want this particular method to have an extended timeout. Thanks! :)
The transaction timeout value that you specify on
UserTransaction.setTransactionTimeout()
should be constrained by the Maximum Transaction Timeout, but not by the Total Transaction Lifetime Timeout, so you would need to increase the former to at least 1200 seconds if you want the application to be able to set the transaction timeout to 1200 seconds, whereas the latter can remain at a lesser value, and would continue to apply where the application does not specify a transaction timeout. Descriptions of these settings are found in this knowledge center doc,https://www.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/udat_contranserv.html?lang=en
It should also be noted that
UserTransaction.setTransactionTimeout()
should be invoked before beginning the transaction, and only applies to the transaction that will run on the same thread, so you'll want to verify that your application is using it in this manner.If you have already done the above and the product is behaving differently, I would suggest opening a case with IBM support.
In addition to setting the transaction timeout on the UserTransaction itself, you can also increase the transaction timeout values for WebSphere at:
Servers > Server Types > WebSphere application servers > server_name >
[Container Settings] Container Services > Transaction Service
IBM Doc: Transaction Service Settings