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

时间:2012-01-21 16:07:12

标签: java java-ee

我一直在研究如何解决这个问题,但似乎无法找到合适的解决方案。

问题在于:

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

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

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

我已经通过在项目上设置一个标志inInse,将其实现为true,然后检查它。当用户完成编辑项目时,通过单击“保存”或“取消”,该标志将设置为false。 这种方法的问题在于考虑用户打开浏览器或浏览器关闭的情况。

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

也许这是错误的方法,因为它似乎是许多应用程序可能存在的问题,并且应该存在较少的hackie解决方案。

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

我找到了这个解决方案Only one user allowed to edit content at a time,但不确定这是否是Java的方法。

是否有更优雅的/ java解决方案?如果是这样,你能指出我正确的方向吗?你会如何实现这个?

谢谢!

解决方案: 虽然最初我认为乐观锁定是要走的路,但我很快意识到它对我的环境不起作用。我决定采用悲观锁定(http://www.agiledata.org/essays/concurrencyControl.html#PessimisticLocking)和超时的组合。

当访问某个项目时,我将inUse字段设置为true,将对象的最后访问字段设置为当前时间。

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

4 个答案:

答案 0 :(得分:3)

就像在使用时间戳的数据库中一样。时间戳与记录保持一致,当一个人提交他的编辑时,编辑不会通过,除非时间戳是相同的(意思是“自从我读取此记录后没有发生编辑”#39;)。然后,当编辑确实通过时,会创建一个新的时间戳。

答案 1 :(得分:0)

听起来你可以使用:Session Beans引用:

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

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

答案 2 :(得分:0)

首先,在你的持久层中,你真的应该使用版本/时间戳字段进行optimistic locking

在UI级别,为了处理您的用例,我会执行资源租赁

  1. 在表格中添加两个字段:

    • LAST_LEASE_TIME:上次租约的时间
    • LAST_LEASE_USER:最后一次租借记录的用户。
  2. 当用户尝试编辑您的记录时,首先检查该记录是否未租用,或者租约是否已过期(即租约未超过指定的租约时间)或用户是被授予租约的人。

  3. 从您的网络浏览器中,定期续订租约,例如通过AJAX通话。

  4. 当用户结束编辑记录时,显式使租约到期。

  5. 通过租赁,您解决了“关闭浏览器”问题:在租约期满后没有任何租赁改造,算法会自动“释放”资源。

答案 3 :(得分:0)

Martin Fowler描述了这种问题的4种模式:

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