0

我有一定的资源我想限制访问。基本上,我使用的是会话级锁。然而,编写涵盖所有可能关闭窗口的方式的 JavaScript 变得越来越痛苦。

一旦用户离开该页面,我想解锁资源。

我的基本想法是使用某种服务器端超时来解锁资源。基本上,如果我无法解锁资源,我想要一个计时器来启动并解锁资源。

例如,在客户端更新 30 秒后,解锁资源。

我的基本问题是,我可以使用什么样的技巧来做到这一点?我的理解是,我不能只在 JSF 中创建一个线程,因为它是不受管理的。

我确信其他人会做这种事情,正确的使用方法是什么?

谢谢,格雷

4

1 回答 1

1

正如 BalusC 完全问的那样,最大的问题是您希望在什么粒度级别上执行此锁定?每个登录用户,所有用户,或者您可以通过每个请求锁定?

或者,这将是一个更难的问题,是单页请求获取锁然后该特定页面旨在保持请求之间的锁的想法吗?例如,作为一种预订。我正在浏览一个酒店页面,当我只是查看一个房间时,我已经在系统中为该房间进行了隐式预订,所以在我查看时不会发生其他人真实预订房间的情况?

在后一种情况下,也许以下方案会起作用:

  1. 在应用范围内,定义一个全局并发映射。
  2. 地图的键代表您要保护的资源。
  3. 映射的值是一个自定义结构,它持有一个读写锁(例如 ReentrantReadWriteLock)、一个令牌和一个时间戳。
  4. 在应用范围内,还有一个全局锁(如 ReentrantLock)
  5. 请求中的代码首先获取全局锁,然后快速检查映射中的条目是否存在。
  6. 如果该条目在那里,则它被采用,否则它被创建。创建时间应该很短。全局锁很快被释放。
  7. 如果条目是新的,它会通过它的写锁被锁定,并创建一个新的令牌和时间戳。
  8. 如果条目不是新条目,则通过其读锁锁定
  9. 如果代码具有相同的令牌,它可以继续访问受保护的资源,否则它检查时间戳。
  10. 如果时间戳已过期,它会尝试获取写锁。
  11. 写锁超时。当超时发生时,放弃并向客户传达一些信息。否则会创建一个新的令牌和时间戳。

这只是一般的想法。在我构建的 Java EE 应用程序中,我使用了类似的东西(尽管不完全相同)并且效果很好。

或者,您无论如何都可以使用定期删除过时条目的石英作业。另一个替代方案是用例如 JBoss Cache 或 Infinispan 实例替换全局并发映射。这些允许您为其条目定义驱逐策略,这使您不必自己编写代码。但是,如果您从未使用过这些缓存,那么学习如何正确设置和配置它们可能比自己构建一个简单的石英作业更麻烦。

于 2010-12-29T17:25:16.533 回答