最近我在工作中被问到这个问题。
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。
这是我的解决方案:
当用户A进入屏幕并锁定记录A时,将时间戳记设置为
静态地图:Map<String, Long> timeUsers = <userId, System timestamp>
每次用户(userA,userB等)向服务器发送请求,并使用每个userId更新或设置时间戳。
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的状态已更改。将值保留在静态变量中...
有人对此有其他解决方案吗?
答案 0 :(得分:0)
客户端上的任何内容都是不好的,因为如果您向外扩展,它可能会崩溃并且无法正常工作。将status
1/0替换为locked_until_ts
。 (可选)添加一个locked_by
,以便B可以与A通话。在锁到期之前,不可能从别人那里抢到锁(但是可以从自己那里抢到)。您可能需要同时添加一个版本列以进行乐观锁定。
答案 1 :(得分:0)
为此,您需要在数据库中存储用户的每个操作的时间戳,而不是状态。每当有人加载用户时,是否可以收集用户是否可点击的信息。基本上,您沿着用户信息加载时间戳,并查看时间戳是否在最近的60秒内。如果是这样,那么,如果用户尝试单击另一个用户,那么您甚至不需要向服务器发送请求。如果时间已过去,则您将需要从服务器请求时间戳,并查看用户是否可单击,或者自上次检查以来用户是否已执行其他操作。另外,如果某个用户被加载为可点击,则当另一个用户单击该用户时,您将需要检查此时间戳,以确保另一个用户在最近60秒内未执行任何操作。