我的Spring MVC的DeferredResult类的使用造成的Tomcat默默地崩溃 [英] My use of Spring MVC's DeferredResult class causes Tomcat to crash silently

查看:3364
本文介绍了我的Spring MVC的DeferredResult类的使用造成的Tomcat默默地崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的Spring MVC 3.2 code(它使用<一个href=\"http://static.springsource.org/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/context/request/async/DeferredResult.html\"相对=nofollow> DeferredResult类):

I have the following Spring MVC 3.2 code (it uses the DeferredResult class):

@RequestMapping(value = "getMessages", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public DeferredResult<List<Message>> getMessages(@RequestParam final Long senderId) {
        final Long recipientId = memberService.retrieveCurrentMember().getId();
        final String messageRequestKey = new StringBuilder().append(senderId).append(":").append(recipientId).toString();
        final DeferredResult<List<Message>> deferredResult = new DeferredResult<List<Message>>(null, Collections.emptyList());
        messageRequests.put(messageRequestKey, deferredResult);

        deferredResult.onCompletion(new Runnable() {
            @Override
            public void run() {
                messageRequests.remove(messageRequestKey);
            }
        });

        List<Message> unReadMessages = messageService.findUnreadMessages(senderId, recipientId);
        if (!unReadMessages.isEmpty()) {
            deferredResult.setResult(unReadMessages);
        }
        return deferredResult;
    }

这方法是通过Ajax调用连续调查,并系统地使Tomcat能够在第九届方法调用崩溃。需要注意的是Tomcat的崩溃没有任何错误信息。

This method is polled continuously by an ajax call and it systematically causes Tomcat to crash upon the 9th method invocation. Note that Tomcat crashes without any error message.

我会很感激,如果有人可以帮助我判断之所以这样code表现出这种行为,或许可以让我对如何调试应用程序/ tomcat的提示。

推荐答案

我想你的修改<一个href=\"http://forum.springsource.org/showthread.php?135927-Unknown-threading-issue-causes-async-Spring-controller-method-to-leak-db-connections\"相对=nofollow> MVC-聊天code 。

有了它,一个GET请求尽快发出,我签入和自超时是3秒,它已逾时和GET反应过来与消息的空列表。客户端立即发出响应于该另一个GET请求,并且第二GET挂内部myService.someTransactionalMethod();在调用messageRepository.findAll(); !

with it, a GET request was issued as soon as I signed-in and since the timeout was 3sec, it timedout and the GET response came with an empty list of messages. The client immediately issued another GET request in response to this, and the second GET hung inside "myService.someTransactionalMethod();" in the call to "messageRepository.findAll();" !

如果我增加超时,让GET请求完整的,那么随后的GET请求能够正确地调用启用的Tx-方法。
但是,如果一个请求已逾时,随后的GET请求(来自同一聊天客户端)被阻塞在启用的Tx-方法。 (即与清理的问题)。

If I increase the timeout and let the GET request 'complete', then a subsequent GET request is able to call the Tx-enabled method properly. But if a request 'timedout', a subsequent GET request (from the same chat client) is blocked in the Tx-enabled method. (i.e a problem with clean-up).

类似地,当一个GET突出和一个平行的GET发出(例如,从其他浏览器窗口)的第二个GET获取阻塞在启用的Tx-方法

Similarly, when a GET is outstanding and a parallel GET is issued (say, from another browser window) the second GET gets blocked in the Tx-enabled method.

这似乎与DeferredResult与OEMIV过滤器的语义交互的问题。
您已通过在春季论坛上提出这个做正确的事!

This seems a problem with the DeferredResult's interaction with OEMIV filter's semantics. You have done the right thing by raising this in the Spring forum !

EDIT1:为了证实上述说法,我删除从XML的OEMIV过滤器(并留下所有其他code,含热力方法和DeferredResult,不变)和它的工作没有任何问题的。

To confirm the above claim, I removed the OEMIV filter from xml (and left ALL other code, including the Tx method and the DeferredResult, unchanged) and it worked without any issues.

EDIT2:罗森Stoyanchev评论了春天论坛上表示:

Rossen Stoyanchev commented on the Spring forum that :

"On the initial request thread, the OEMIV filter acquires an EM instance, then the 
 controller is invoked, which in turn invokes the tx method. The tx method re-uses the 
 same EM instance. Then the controller method returns and the Servlet container thread 
 is exited, but OEMIV filter doesn't release the EM instance because it is aware of the 
 async processing.
 When the DeferredResult is set, a dispatch is made back to the container, hitting the 
 OEMIV filter and the DispatcherServlet once again. When that thread completes, OEMIV 
 filter will release the EM instance. Note that this is true even if the DeferredResult
 is set in the controller method.".

从上面的,它看起来好像,当异步请求超时,OEMIV过滤器或者未卷入即使它不涉足它没有得到一个机会来释放EM实例,它持有。

From the above, it looks as if, when the async request times out, the OEMIV filter is either not getting involved and even if it does get involved it does not get a chance to release the EM instance that it holds.

这篇关于我的Spring MVC的DeferredResult类的使用造成的Tomcat默默地崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆