如何设置一个锁,如果没有收到保持活动信号,该锁将自动超时?

发布于 2024-10-09 18:04:42 字数 304 浏览 2 评论 0原文

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

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

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

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

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

我确信其他人也这样做,那么正确的使用方法是什么?

谢谢, 格雷

I have a certain resouce I want to limit access to. Basically, I am using a session level lock. However, it is getting to be a pain writing JavaScript that covers every possible way a window can close.

Once the user leaves that page I would like to unlock the resouce.

My basic idea is to use some sort of server side timeout, to unlock the resouce. Basically, if I fail to unlock the resource, I want a timer to kick in and unlock the resouce.

For example, after 30 seconds with now update from the clientside, unlock the resouce.

My basic question, is what sort of side trick can I use to do this? It is my understanding, that I can't just create a thread in JSF, because it would be unmanaged.

I am sure other people do this kind of thing, what is the correct thing to use?

Thanks,
Grae

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空名 2024-10-16 18:04:42

正如 BalusC 所问的那样,最大的问题是您希望以什么粒度级别进行锁定?每个登录用户,对于所有用户,或者也许您可以摆脱每个请求的锁定?

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

在后一种情况下,也许以下方案可行:

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

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

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

As BalusC right fully asked, the big question is at what level of granularity would you like to do this locking? Per logged-in user, for all users, or perhaps you could get away with locking per request?

Or, and this will be a tougher one, is the idea that a single page request grabs the lock and then that specific page is intended to keep the lock between requests? E.g. as a kind of reservation. I'm browsing a hotel page, and when I merely look at a room I have made an implicit reservation in the system for that room so it can't happen that somebody else reserves the room for real while I'm looking at it?

In the latter case, maybe the following scheme would work:

  1. In application scope, define a global concurrent map.
  2. Keys of the map represent the resources you want to protect.
  3. Values of the map are a custom structure which hold a read write lock (e.g. ReentrantReadWriteLock), a token and a timestamp.
  4. In application scope, there also is a single global lock (e.g. ReentrantLock)
  5. Code in a request first grabs the global lock, and quickly checks if the entry in the map is there.
  6. If the entry is there it is taken, otherwise it's created. Creation time should be very short. The global lock is quickly released.
  7. If the entry was new, it's locked via its write lock and a new token and timestamp are created.
  8. If the entry was not new, it's locked via its read lock
  9. if the code has the same token, it can go ahead and access the protected resource, otherwise it checks the timestamp.
  10. If the timestamp has expired, it tries to grab the write lock.
  11. The write lock has a time-out. When the time-out occurs give up and communicate something to the client. Otherwise a new token and timestamp are created.

This just the general idea. In a Java EE application that I have build I have used something similar (though not exactly the same) and it worked quite well.

Alternatively you could use a quartz job anyway that periodically removed the stale entries. Yet another alternative for that is replacing the global concurrent map with e.g. a JBoss Cache or Infinispan instance. These allow you to define an eviction policy for their entries, which saves you from having to code this yourself. If you have never used those caches though, learning how to set them up and configuring them correctly can be more trouble than just building a simple quartz job yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文