如何检测记录锁定时间过长?

时间:2018-07-13 08:37:06

标签: java oracle algorithm struts2 spring-mybatis

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

db(数据库)中有一些记录。例如,我们有recordA,recordB,....

[库存管理]屏幕显示它们的成分。

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

数据库中的记录。

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

用户A登录系统,在[股票管理]屏幕中单击recordA进行编辑,recordA的状态为“锁定”。

db中的记录A的状态

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

目前,用户B不能更改记录A。当userB单击recordA时,将显示错误消息“ recordA被锁定

现在我需要实现此逻辑“ 从userA发送60秒后,如果用户不向服务器发送任何请求,请单击recordA。userB可以单击recordA进行编辑 < / strong>”

框架:Struts2,Spring-ibatis,Oracle数据库,Java。

这是我的解决方案:

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

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

  3. UserB进入屏幕,并查看recordA的状态已锁定。用户B单击recordA,

    我将检查:时间userB单击记录A-时间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
    

但是我认为这不是很好。 UserA无法看到recordA的状态已更改。将值保留在静态变量中...

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

2 个答案:

答案 0 :(得分:0)

客户端上的任何内容都是不好的,因为如果您向外扩展,它可能会崩溃并且无法正常工作。将status 1/0替换为locked_until_ts。 (可选)添加一个locked_by,以便B可以与A通话。在锁到期之前,不可能从别人那里抢到锁(但是可以从自己那里抢到)。您可能需要同时添加一个版本列以​​进行乐观锁定。

答案 1 :(得分:0)

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