【问题标题】:How to detect a record is locked too long?如何检测一条记录被锁定的时间过长?
【发布时间】:2018-07-13 08:37:05
【问题描述】:

我最近在工作中被问到这个问题。

db(database)中有一些记录。例如,我们有recordA、recordB、...。

[库存管理]屏幕显示他们的内容。

有一些用户。我们有 userA, userB, ...

db 中的记录。

recordId ...userId....  status(locked=1, unlocked=0)
--------------------------
recordA     userA       0
recordA     userB       0
recordB     userA       0
recordB     userB       0
...

userA登录系统,在【库存管理】界面点击recordA进行编辑,recordA的状态为'locked'。

db 中记录 A 的状态

recordId ...userId....  status(locked=1, unlocked=0)
--------------------------
recordA     userA       1
recordA     userB       0
recordB     userA       0
recordB     userB       0
...

目前,用户 B 无法更改记录 A。当用户B点击记录A时,它会显示错误消息“记录A被锁定

现在我需要实现这个逻辑“如果用户没有向服务器发送任何请求,则在用户 A 60 秒后单击记录 A。用户 B 可以单击记录 A 进行编辑"

框架: Struts2、Spring-ibatis、Oracle db、Java。

这是我的解决方案:

  1. 当用户A进入屏幕并锁定记录A时,将时间戳设置在 静态地图:Map<String, Long> timeUsers = <userId, System timestamp>

  2. 每次用户(userA、userB、...)向服务器发送请求时,使用每个 userId 更新或设置时间戳。

  3. UserB 进入屏幕,看到 recordA 的状态被锁定。用户B点击记录A,

    我会检查:时间 userB 点击记录 A - time userA 保存在静态地图中

      If(time userB click on recordA - time userA is kept in Map<String, Long> 
        )> 60 (s){
    
        - Update db. Change status of recordA(1->0) with userA
        - Update db. Change status of recordA(0->1) with userB
      } 
    
     db is updated
    
     recordId ...userId....  status(locked=1, unlocked=0)
     --------------------------
     recordA        userA       0
     recordA        userB       1
     recordB        userA       0
     recordB        userB       0
    

但我认为它不是那么好。用户 A 看不到记录 A 的状态已更改。将值保存在静态变量中...

有人对此有其他解决方案吗?

【问题讨论】:

  • 当A点击的时候,你为什么不启动一个一分钟后解锁A的定时器呢?
  • Java 中有一个方便的类,叫做ScheduledExecutorService。看看吧。
  • @YvesDaoust:如果用户在 60 秒内向服务器发送请求。您需要检查服务器。如果用户A点击记录A,然后点击记录B,计时器太多。
  • @Noname:在服务器上启动锁和计时器。 (如果 A 过早解锁,则应终止计时器。)
  • @YvesDaoust:如果用户 A 在 60 秒内发送请求。定时器总是需要重新设置。如果当用户成功锁定记录时我们有很多计时器会发生什么。我认为这很复杂

标签: java oracle algorithm struts2 spring-mybatis


【解决方案1】:

客户端的任何东西都是不好的,因为它可能会崩溃并且如果您向外扩展将无法工作。将status 1/0 替换为locked_until_ts。可以选择添加locked_by,以便 B 可以与 A 交谈。在锁过期之前,不可能从别人那里抢到锁(但可以从自己那里抢)。您可能希望同时为乐观锁定添加版本列。

【讨论】:

    【解决方案2】:

    为此,您需要在数据库中存储用户每个操作的时间戳,而不是状态。每当有人加载用户时,是否可以收集用户是否可点击的信息。基本上,您会沿着用户信息加载时间戳,并查看它是否在最后 60 秒内。如果是这样,那么如果用户尝试单击其他用户,您甚至不需要向服务器发送请求。如果时间已过,那么您将需要从服务器请求时间戳,并查看用户是否可点击,或者自上次检查以来他或她是否执行了其他操作。另外,如果一个用户被加载为可点击,当另一个用户点击该用户时,您需要检查这个时间戳,以确保另一个用户在过去 60 秒内没有做任何事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多