【问题标题】:Session not committed before the end of function会话未在函数结束前提交
【发布时间】:2013-07-18 22:59:08
【问题描述】:

我有一个需要 50 秒来处理的大动作。 但是,与此同时,我还有另一个可以在服务器上处理的操作(通过单击链接)。

但是,如果我的第二个操作尝试访问我的第一个操作放置的会话属性,则它们在第一个操作结束之前可用。

这是我的大动作:

public String bigAction() {
    HttpSession session = request.getSession();
    synchronized (session) {
        for(int i = 0 ; i < 100000 ; ++i)
             session.setAttribute("foo_"+i, "bar");
        }
    return SUCCESS;
}

这是我的小动作:

public String smallAction() {
    HttpSession session = request.getSession();
    synchronized (session) {
        session.getAttribute("foo_1", "bar");
    }
    return SUCCESS;
}
第一个动作:--------------------------------------------------------- 第二个动作: --- -- --- - ---

因此,在此示例中,我的第二个操作需要由第一个操作创建的会话属性,但实际上它们并不存在。

如何同步我的会话?

【问题讨论】:

  • 但这不能保证进程的同步!可能很少的 sn-p 代码将有助于理解您的问题。
  • 我已经编辑了我的问题来展示一个例子。

标签: session jakarta-ee httpsession


【解决方案1】:

根据 Servlet 规范:

执行请求线程的多个 servlet 可以同时对同一个会话对象进行主动访问。容器必须确保以线程安全的方式执行表示会话属性的内部数据结构的操作。开发人员负责对属性对象本身进行线程安全访问。这将保护 HttpSession 对象内的属性集合免受并发访问,从而消除应用程序导致该集合损坏的机会。

这是安全的:

request.getSession().setAttribute("bar", "foo");

不保证安全:

HttpSession session = request.getSession();
synchronized (session) {
   String value = (String) session.getAttribute("bar");
}

此外,如果在同一个对象上,锁将起作用,不要依赖request.getSession() 返回相同的对象。 Servlet 规范中没有任何内容说 HttpServletSession 实例在每次被请求时都不能作为外观对象重新创建。

阅读Java theory and practice: Are all stateful Web applications broken?How HttpSession is not thread safe

这里定义了一种方法,Java-synchronizing-on-transient-id

【讨论】:

  • 我试着按照教程,关于上面的解释。我试图这样做,但是,我有同样的问题。我对 IdMutexProvider 进行了静态引用,但会话的 id 在两种情况下都不同。
【解决方案2】:

今天的变化:

我使用的是 Struts 2,所以我实现了 SessionAware,因为我读到它可能是一个很好的解决方案。但这是一样的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 2015-03-30
    • 2011-05-23
    相关资源
    最近更新 更多