gpt4 book ai didi

c# - 并发选择唯一记录

转载 作者:行者123 更新时间:2023-11-30 23:07:12 27 4
gpt4 key购买 nike

我看过其他策略,但我想知道这种并发选择唯一记录的策略是否有任何缺点。换句话说:如果两个线程同时运行并尝试在同一时间选择记录,它们将永远不会选择相同的记录。

给定表 TableName,包含包含 ProcessID 的列,其默认值为 NULL

为清晰起见进行编辑:ProcessID 不是标识或自动递增字段。它可能是也可能不是 Processes 表的 FK,但这尚未确定。此时它只是代码的标识符。

var myGUID = Guid.NewGuid();
ExecuteCommand("UPDATE TableName SET ProcessID = @myGUID WHERE ProcessID IS NULL", myGUID);
var myThreadsUniqueRecords = Query("SELECT * FROM TableName WHERE ProcessID = @myGUID", myGUID);

我删除了处理异常、回滚和跟踪的代码(如果 ProcessID 之前已更新,然后孤立)。我还意识到 GUID 冲突的可能性几乎是不可能的,除非有重要的理由提出它,否则我想忽略它。

问题的目标是:是否有任何理由可以将相同的记录返回到两个不同的线程?我的理解是,SQL Server 将一次一个进程锁定这些记录的选择和更新,因此永远不会对单个记录进行双重更新。

最佳答案

虽然您的方法是安全的,但我建议采用稍微不同的方法。首先,您不需要更新然后单独选择,而是使用 OUTPUT 语句:

UPDATE TableName 
SET ProcessID = @myGUID
OUTPUT INSERTED.*
WHERE ProcessID IS NULL

这将在单个语句中更新和选择受影响的行。

考虑到这句话 - 您实际上不需要使用任何 guid。您甚至可以使用 bool 字段指示当前项目当前是否正在处理:

UPDATE TableName 
SET IsProcessing = true
OUTPUT INSERTED.*
WHERE IsProcessing = false

而且它和使用 guids 一样安全,因为两个事务不能同时更新同一行。您可能想要添加列以指示何时开始处理项目并引入超时来处理工作人员崩溃时的情况。此外,您可能不想同时获取表中的所有行 - UPDATE TOP (x) 有助于此:

UPDATE TOP (10) TableName
SET IsProcessing = true, ProcessingStarted = SYSUTCDATETIME()
OUTPUT INSERTED.*
WHERE IsProcessed = false AND
(IsProcessing = false OR DATEDIFF(minute, ProcessingStarted, SYSUTCDATETIME()) > 60)

关于c# - 并发选择唯一记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47516532/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com