【问题标题】:Hold Lock During Selection选择期间保持锁定
【发布时间】:2019-11-25 12:57:35
【问题描述】:

我们有一些遗留的旧事务表,其中包含 LockedLockDate 列。一次只有一个用户可以选择一个事务(行)。每当用户选择特定事务时,我们都会标记行Locked=1,因此其他用户不能选择相同的事务(直到用户保存事务或我们在一段时间后清除锁定)。问题是在系统负载下,多个用户可以在并发下选择同一个事务。我们正在做,

SELECT TOP 1 * FROM TABLE WHERE Locked=0 AND OurConditions
UPDATE TABLE SET Locked=1 WHERE ID=....

如何在对系统性能影响最小的情况下解决此问题。

【问题讨论】:

  • 您不会通过持有锁来实现签入/签出功能。这将在不解决并发问题的情况下降低可伸缩性。事务和是短暂的。
  • 您可以使用UPDATE WHERE,以确保一次只有一个连接可以结帐/锁定。为什么使用TOP 1?你想实现一个队列吗?这是一个非常不同的非常困难的问题
  • @PanagiotisKanavos 我想要一个简单的用户一次获得一笔交易用于处理目的。

标签: sql sql-server sql-server-2014


【解决方案1】:

locked 添加到您的WHERE

UPDATE YT
SET Locked = 1--, other columns to set
FROM dbo.YourTable YT
WHERE YT.ID = @ID
  AND Locked = 0;

那么当“行”已经被锁定时,其他人无法锁定它。

【讨论】:

  • 意味着即使在多个并发请求下也只有一个会获得锁
  • @user960567 UPDATE WHERE 确保了这一点。你为什么用TOP 1呢?您是否尝试实现队列?这是一个更难的问题
  • 是的,@user960567 因为在处理UPDATE 时,行/表将被锁定。在第一个锁被释放之前,第二个UPDATE 将无法被处理,并且随着基础数据发生变化,UPDATE 不会返回WHERE 中的任何行;因此不会更新。
  • @Larnu 在这种情况下使用Lockedlocks 不是一个好的选择,因为不使用数据库 锁。即使连接关闭,该行也会被标记/签出
  • @user960567 首先不要使用数据库表。如果必须,请使用 单独的 队列表并使用 DELETE OUTPUT as shown here 使用破坏性出列。如果您尝试使用 UPDATE 和锁定 as shown here 来实现队列,您会发现在极少数情况下,对表的正常访问会导致排队场景出现问题,这种情况发生在午夜或您度假时
猜你喜欢
  • 2018-11-01
  • 2020-06-07
  • 2021-04-28
  • 2012-12-09
  • 1970-01-01
  • 2014-02-28
  • 2021-02-20
  • 1970-01-01
  • 2011-11-12
相关资源
最近更新 更多