Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检测记录被锁定的时间过长?_Java_Oracle_Algorithm_Struts2_Spring Mybatis - Fatal编程技术网

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

Java 如何检测记录被锁定的时间过长?,java,oracle,algorithm,struts2,spring-mybatis,Java,Oracle,Algorithm,Struts2,Spring Mybatis,我最近在工作中被问到这个问题 数据库中有一些记录。例如,我们有recordA、recordB [库存管理]屏幕显示它们的成分 有一些用户。我们有userA,userB 以db为单位的记录。 用户登录系统,点击[Stock Management]屏幕中的recordA进行编辑,recordA的状态为“锁定” 记录A的状态(以db为单位) recordId ...userId.... status(locked=1, unlocked=0) -------------------------- r

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

数据库中有一些记录。例如,我们有recordA、recordB

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

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

以db为单位的记录。

用户登录系统,点击[Stock Management]屏幕中的recordA进行编辑,recordA的状态为“锁定”

记录A的状态(以db为单位)

recordId ...userId....  status(locked=1, unlocked=0)
--------------------------
recordA     userA       1
recordA     userB       0
recordB     userA       0
recordB     userB       0
...
目前,userB无法更改recordA。当用户B单击recordA时,它将显示错误消息“recordA已锁定”

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

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

这是我的解决方案:

  • 当userA进入屏幕并锁定recordA时,在中设置时间戳 静态映射:
    Map timeUsers=

  • 每次用户(userA,userB,…)向服务器发送请求时,用每个用户标识更新或设置时间戳

  • UserB进入屏幕并查看recordA的状态是否已锁定。UserB单击recordA

    我将检查:time 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
    
    If(time userB)点击记录a-time userA保存在地图中
    )>六十(s){
    -更新数据库。使用userA更改记录A(1->0)的状态
    -更新数据库。使用userB更改记录A(0->1)的状态
    } 
    数据库已更新
    记录ID…用户ID。。。。状态(锁定=1,解锁=0)
    --------------------------
    记录用户A 0
    记录用户B 1
    recordB userA 0
    记录B用户B 0
    
  • 但我觉得不太好。UserA无法看到recordA的状态已更改。在静态变量中保留值


    有人有其他解决方案吗?

    客户端的任何东西都是不好的,因为它可能会崩溃,如果您向外扩展,它将无法工作。将
    status
    1/0替换为
    locked\u,直到
    。可以选择添加一个
    locked_by
    ,以便B可以与a对话。在锁过期之前,不可能从其他人那里获取锁(但可以从自己那里获取)。您可能希望同时添加一个用于乐观锁定的版本列。

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

    当一个用户点击时,为什么不启动一分钟后解锁的计时器呢?Java中有一个名为
    ScheduledExecutorService
    的简单类。请看一看。@YvesDaoust:如果用户在60秒内向服务器发送请求。您需要签入服务器。如果userA单击记录A,然后单击记录B,则计时器太多。@Noname:锁和计时器在服务器上启动。(如果A过早解锁,计时器应该停止。)@YvesDaoust:if用户A在60秒内发送请求。计时器总是需要重置。当用户成功锁定一条记录时,如果我们有很多计时器会发生什么。我认为这很复杂
      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