假设我有一个名为Task的表:
| ID | TASK | Other columns... |
| 1 | ... | ... |
| 2 | ... | ... |
| 3 | ... | ... |
我有一个存储过程:
此存储过程将由许多客户端应用程序同时调用。如何让存储过程在互斥行上工作? E.g。
答案 0 :(得分:0)
我宁愿建议采用乐观的并发控制方法。这是通过在sql server中使用timestamp列实现的。每次更新记录时,时间戳值都会自动增加。
每当您触发选择查询时,您都必须选择主键列和时间戳列。每当您更新此记录时,您的查询应该如下所示
UPDATE t SET Name = 'XYZ' from Employee t WHERE t.PrimaryKeyColumn = @Col1
AND t.TimeStamp = @Timestamp
IF @@RowCount = 0
BEGIN
RAISEERROR('Record has been updated by another user',16, 1)
END
修改强>
满足您的问题要求
我可以考虑创建一个全局临时表,其中包含一个名为SPID(connectionID)的附加列,其默认值为NULL
select *, NULL AS spId into ##TaskList
这里的关键是这个全局临时表将可用,直到创建它的进程范围。因此,您可以使用一个永久表来执行此任务,或者让临时表的创建者保持活动状态。
由于每个存储过程都将在不同的数据库连接下运行,因此它们都将具有唯一的SPID。
任何处理T1,T3的进程必须在T1,T3上开始进程之前将其SPID更新为此全局临时表。
类似的剩余proc将查询## TaskList以锁定他们想要处理的SPID = NULL的任务。
SELECT * FROM ##TaskList where SPID IS NULL
UPDATE SPID = @@SPID FROM ##TaskList where Task IN (T2, T4)
通过这种方法,所有任务都将与存储过程互斥。