In a webapp we have transaction management using struts2 interceptor
pseudo code of the interceptor
public String intercept(ActionInvocation invocation) throws Exception {
TransactionService.startTransaction();
invocation.invoke();
TransactionService.commitTransaction();
}
when the action returns 'redirect' (302), sometimes the redirected request comes to the server before 'TransactionService.commitTransaction()' is called. ( looks like network call is faster than stack unwinding )
below log message captured explains this
2017-10-04 09:18:37,693 [task-37] DEBUG (interceptors) TransactionInterceptor begin
2017-10-04 09:18:37,949 [task-38] DEBUG (interceptors) TransactionInterceptor begin
2017-10-04 09:18:37,963 [task-37] DEBUG (interceptors) TransactionInterceptor commit
2017-10-04 09:18:37,955 [task-38] ERROR (interceptors) SecurityInterceptor: Failed to execute Action:
in the above log Task-37 ( thread ) suppose to save/update some records in DB and issue a redirect to refresh the view, its interceptor will commit the transaction.
But the redirect thread ( Task - 38 ) reached the server before commit happened.
I am looking at PreResultListener or 'Chain Result'. ( both options have its own issues) I greatly appreciate any input to solve this issue
Thanks in advance.
Here is a working code, kind a worked around with PreResultListener.
public String intercept(ActionInvocation invocation) throws Exception {
invocation.addPreResultListener(new PreResultListener() {
@Override
public void beforeResult(ActionInvocation invocation, String resultCode) {
try {
// commit based on the resultCode comparision
if (StringUtils.equals(resultCode,"302_redirect") {
TransactionService.commitTransaction();
}
// or commparision based on the redirect handler
// Class names are from struts-default.xml
/*
String resultConfigClassName = invocation.getProxy().getConfig().getResults().get(resultCode).getClassName();
if (StringUtils.equals(resultConfigClassName,"org.apache.struts2.dispatcher.ServletRedirectResult")
|| StringUtils.equals(resultConfigClassName, "org.apache.struts2.dispatcher.ServletActionRedirectResult")) {
TransactionService.commitTransaction();
}
*/
}
catch (Exception e) {
// Ignore don't do anything
}
}
});
TransactionService.startTransaction();
invocation.invoke();
TransactionService.commitTransaction();
}