【问题标题】:Portlets, HttpSession and Thread-SafetyPortlet、HttpSession 和线程安全
【发布时间】:2011-07-21 07:22:17
【问题描述】:

我们的 portlet 将状态保存在 HttpSession 中,由同一会话的所有请求处理线程共享。

portlet 规范 (JSR-168) 写道:

PLT.5.2.4.3 请求处理期间的多线程问题

portlet 容器通过并发处理对同一个 portlet 的并发请求 在不同线程上执行请求处理方法。 Portlet 开发人员必须 设计他们的 portlet 以处理来自内部的多个线程的并发执行 processActionrender 方法在任何特定时间。

我想知道我应该如何实现这一目标?当然,我可以在processActionrender 期间使用同步来实现互斥,但是我看不到如何在整体上强制执行请求处理的原子性。特别是,我担心以下情况:

  • 线程 1 执行 processAction,将数据加载到会话中以供稍后渲染
  • 线程 2 执行 processAction,从会话中丢弃该数据
  • 线程 1 执行 render,从会话中读取要呈现的数据,并抛出 NullPointerException,因为准备好的数据不再存在...

通常如何防止这种情况发生?特别是在使用 JBoss portlet 桥将 JSF 适配到 Portlet 环境时?

【问题讨论】:

    标签: java multithreading jsf session-state portlet


    【解决方案1】:

    我想说,如果有两个 portlet 对相同的数据进行操作,尤其是一个读取它而另一个删除它,那么设计中很可能存在严重缺陷。

    然后您可能希望存储每个 portlet/线程的数据,即如果 portlet1 读取一些数据,您应该写入锁定它直到读取完成并使用唯一键将其放入会话中。

    如果删除应该呈现的数据是合法的,那么你应该考虑到这一点并在render期间再次检查。

    【讨论】:

    • 您误会了:这是同一个portlet,服务器同时处理两个请求,因为用户单击了第二个按钮,而前一个单击仍在处理中。不,状态必须在请求中可见(因为后续请求可能对相同的数据进行操作,我不想从数据库中重新加载它),所以我不能将它绑定到线程。
    • 嗯,这取决于用例,但我不允许用户在当前完成之前触发另一个动作。示例:用户加载一些数据,然后单击“删除”而实际上没有看到它。从业务角度来看,这将非常容易出错。如果这仍然可能发生,那么您需要考虑这一点 - 例如在渲染时检查数据是否仍然存在以及在该操作期间锁定它。
    • 所以即使我设法同步服务器上的整个请求处理,这仍然不足以使实际的业务事务原子化,任何使业务事务原子化的东西都可以轻松解决并发问题服务器。这是一个很好的观点,因此我将考虑在客户端做一些事情。非常感谢!
    • 您还可以检查当前是否有针对服务器端的特定 portlet 执行的操作,以防客户端检查失败或以某种方式绕过。
    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2011-06-09
    • 2014-03-04
    相关资源
    最近更新 更多