在webapp中,我们使用struts2拦截器进行事务管理
拦截器的伪代码
public String intercept(ActionInvocation invocation) throws Exception {
TransactionService.startTransaction();
invocation.invoke();
TransactionService.commitTransaction();
}
当操作返回“重定向”(302)时,有时重定向的请求在调用“TransactionService.commitTransaction()”之前到达服务器。 (看起来网络调用比堆栈展开更快)
下面记录的日志消息解释了这个
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:
在上面的日志中任务-37(线程)假设保存/更新DB中的一些记录并发出重定向来刷新视图,其拦截器将提交事务。
但重定向线程(Task-38)在提交之前到达了服务器。
我正在查看PreResultListener或'Chain Result'。 (两个选项都有自己的问题)我非常感谢解决这个问题的任何输入
提前致谢。
答案 0 :(得分:0)
这是一个工作代码,与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();
}