Java 并发性:一次只能有一个用户编辑一个项目

Java 并发性:一次只能有一个用户编辑一个项目,java,jakarta-ee,Java,Jakarta Ee,一段时间以来,我一直在研究如何解决这个问题,但似乎找不到合适的解决方案 问题是: 我有一个JavaEE应用程序,其中许多用户可以登录,他们会看到一个项目列表,他们可以选择和编辑其中的任何一个 所有用户都会看到相同的项目列表。 如前所述,他们可以编辑项目,但我想将编辑功能限制为一个用户。也就是说,许多用户可以同时编辑不同的项目,但只有一个用户可以编辑特定的项目 当一个用户正在编辑某个项目时,试图编辑该项目的任何其他用户都会看到一条消息 我通过将项inUse上的标志设置为true,然后进行检查来实现

一段时间以来,我一直在研究如何解决这个问题,但似乎找不到合适的解决方案

问题是:

我有一个JavaEE应用程序,其中许多用户可以登录,他们会看到一个项目列表,他们可以选择和编辑其中的任何一个

所有用户都会看到相同的项目列表。 如前所述,他们可以编辑项目,但我想将编辑功能限制为一个用户。也就是说,许多用户可以同时编辑不同的项目,但只有一个用户可以编辑特定的项目

当一个用户正在编辑某个项目时,试图编辑该项目的任何其他用户都会看到一条消息

我通过将项inUse上的标志设置为true,然后进行检查来实现这一点。当用户通过单击“保存”或“取消”编辑完项目后,该标志将设置为false。 这种方法的问题是要考虑用户打开浏览器或关闭浏览器的情况

我尝试设置会话超时,但似乎无法使其生效,因为当会话超时时,我无法访问该项目。我只能访问httprequest会话id

也许这是一种错误的方法,因为这似乎是许多应用程序都会遇到的问题,并且应该存在一个不太黑客的解决方案

我研究了使用线程和同步方法,但不知道这将如何工作,因为一旦用户进入编辑项屏幕,该方法就会退出并释放锁

我找到了这个解决方案,但不确定这是否是Java的发展方向

是否有更优雅的/java解决方案?如果是的话,你能给我指一下正确的方向吗?您将如何实现这一点

谢谢

解决方案: 虽然最初我认为乐观锁定是一种方式,但我很快意识到它对我的环境并不起作用。我决定使用悲观锁定()和超时的组合

访问项目时,我将inUse字段设置为true,并将对象上次访问的字段设置为当前时间


每次有人试图编辑对象时,我都会检查inUse字段和lastAccessed字段+5分钟。所以基本上,我给5分钟来编辑用户

像在使用时间戳的数据库中一样进行操作。时间戳与记录一起保存,当一个人提交他的编辑时,编辑不会通过,除非时间戳相同(意思是“自从我阅读此记录以来,没有发生任何编辑”)。然后,当编辑完成时,将创建一个新的时间戳。

听起来您可以使用:Quote:

通常,如果出现以下情况,则应使用会话bean:

在任何给定的时间,只有一个客户机可以访问bean实例。
bean的状态不是持久性的,只存在很短的一段时间(可能几个小时)。

首先,在持久性层中,您确实应该使用版本/时间戳字段

在UI级别,为了处理您的用例,我将进行资源租赁:

  • 向表中添加两个字段:

    • 上次租赁时间
      :上次租赁的时间
    • LAST\u LEASE\u USER
      :上次租用记录的用户
  • 当用户试图编辑您的记录时,请首先检查该记录是否未被租用,或租约是否已过期(即,租约未超过指定的租约时间),或该用户是否是被授予租约的用户

  • 从web浏览器定期续订租约,例如使用AJAX调用

  • 当用户结束编辑记录时,显式终止租约


  • 通过租赁,您可以解决“关闭浏览器”问题:在租赁期到期且没有任何租赁更新后,算法会自动“释放”资源。

    Martin Fowler介绍了4种解决此问题的模式:

  • 在线乐观锁定
  • 在线悲观锁定
  • 离线乐观锁定
  • 离线悲观锁定
  • 你应该根据你的问题决定使用哪一种。 JPA、JDO和Hibernate提供了开箱即用的1和2。 Hibernate也可以处理3(我不确定JPA和JDO)。
    没有一个可以处理开箱即用的4,您应该自己实现它。

    您将编辑用户与其编辑项之间的关联存储在哪里?为什么不能从会话侦听器访问项目?项目对象有一个inUse字段,这就是我要更新的全部内容。httpSession仅存储与http会话相关的内容。因此,无法可靠地访问它。那么,一旦用户发布了允许编辑项目的表单,您在哪里找到要编辑的项目?为什么不将用户编辑的项目列表存储在会话(或数据库)中?当会话超时时,您可以轻松地将切换为不使用。谢谢,我将研究乐观锁定。我使用了乐观锁定方法,它工作得很好。谢谢所有乐观的人。OP需要悲观锁定。@Mark Robbins您能解释一下如何初始化时间戳吗?我的意思是,如果有两个用户想要编辑该项目,你如何区分第一个用户已经锁定了该项目?我相信@Mark指的是这个@user1161661,作者已经在帖子中提到过,所以他知道我的例子是乐观锁定,但是悲观锁定可以通过提供过期的时间戳,并且只允许从该时间戳进行更新来实现。这很有趣,因为它描述了所有可能的策略,但是您应该提供一个指向所有这些策略的描述的链接。