Sql 如何锁定一行,并在多个事务中使用该锁?

Sql 如何锁定一行,并在多个事务中使用该锁?,sql,locking,azure-sql-database,race-condition,Sql,Locking,Azure Sql Database,Race Condition,我的情况是,我需要: 读取一行的值 如果某列的值为“X”,则执行操作A。否则,执行操作B 如果执行了操作A,请使用操作的结果更新列 操作A不是数据库操作,可能需要一段时间才能运行,并且是不可逆的。操作B不是数据库操作,但运行速度非常快。该序列在多个服务器的多个线程上执行 目前我们没有锁定,所以偶尔我们会看到动作A被执行多次,而它只应该发生一次。我认为我唯一的解决方案是用一个获取锁步骤和一个释放锁步骤来包装上面的序列,我不知道怎么做 我已经看到,答案是在行中添加“locked”和“acquiry

我的情况是,我需要:

  • 读取一行的值
  • 如果某列的值为“X”,则执行操作A。否则,执行操作B
  • 如果执行了操作A,请使用操作的结果更新列
  • 操作A不是数据库操作,可能需要一段时间才能运行,并且是不可逆的。操作B不是数据库操作,但运行速度非常快。该序列在多个服务器的多个线程上执行

    目前我们没有锁定,所以偶尔我们会看到动作A被执行多次,而它只应该发生一次。我认为我唯一的解决方案是用一个获取锁步骤和一个释放锁步骤来包装上面的序列,我不知道怎么做

    我已经看到,答案是在行中添加“locked”和“acquiry time”列。然而,在这种情况下,OP并不担心频繁地重新获得锁。如果每次我想执行序列时都必须旋转等待前一个锁过期,那么我的服务器的性能可能会被忽略

    SQL中有内置的东西可以在这里使用吗?

    将“X”值更新为“pending”

    完成行动A后,将“待定”更新为任何内容

    无需锁定。

    将“X”值更新为“待定”

    完成行动A后,将“待定”更新为任何内容


    不需要锁定。

    这是否仍然有可能两个线程同时查询该行,因此两个线程都将该行视为“X”,并尝试将其更新为挂起?@Andrewilliamson:如果您选择了中间层,然后进行了更新。但是如果你只是做了一个更新,那应该是原子的(除非你玩的是SET-ISOLATION_-LEVEL游戏)。这不是仍然有机会两个线程同时查询该行,因此两个线程都将该行视为“X”吗,两人都试图将其更新为挂起?@Andrewilliamson:如果您对中间层进行了选择,然后进行了更新。但如果你只是做了一个更新,那应该是原子的(除非你在玩集合级游戏)。