Sql server 获得;“下一步”;SQL Server数据库中的行,并在单个事务中标记它
我有一个SQL Server表,用作队列,它由一个多线程(即将成为多服务器)应用程序处理。我想让一个进程声明队列中的下一行,将其标记为“进程内”,而不允许多个线程(或多个服务器)同时声明同一行 是否有方法更新行中的标志并同时检索该行?我想要这样的伪代码,但理想情况下,不阻塞整个表:Sql server 获得;“下一步”;SQL Server数据库中的行,并在单个事务中标记它,sql-server,tsql,transactions,queue,Sql Server,Tsql,Transactions,Queue,我有一个SQL Server表,用作队列,它由一个多线程(即将成为多服务器)应用程序处理。我想让一个进程声明队列中的下一行,将其标记为“进程内”,而不允许多个线程(或多个服务器)同时声明同一行 是否有方法更新行中的标志并同时检索该行?我想要这样的伪代码,但理想情况下,不阻塞整个表: Block the table to prevent others from reading Grab the next ID in the queue Update the row of that item wit
Block the table to prevent others from reading
Grab the next ID in the queue
Update the row of that item with a "claimed" flag (or whatever)
Release the lock and let other threads repeat the process
使用T-SQL实现这一点的最佳方法是什么?我记得有一次看到一条语句,它将删除行,同时将删除的行放入临时表中,以便您可以对它们执行其他操作,但我现在无法找到它。主要是在事务中使用如下所示的表提示组合
DECLARE @NextId INTEGER
BEGIN TRANSACTION
SELECT TOP 1 @NextId = ID
FROM QueueTable WITH (UPDLOCK, ROWLOCK, READPAST)
WHERE BeingProcessed = 0
ORDER BY ID ASC
IF (@NextId IS NOT NULL)
BEGIN
UPDATE QueueTable
SET BeingProcessed = 1
WHERE ID = @NextID
END
COMMIT TRANSACTION
IF (@NextId IS NOT NULL)
SELECT * FROM QueueTable WHERE ID = @NextId
UPDLOCK
将锁定它找到的下一个可用行,防止其他进程获取该行。ROWLOCK
将确保仅锁定单个行(我从未发现不使用此选项会有问题,因为我认为它无论如何只会使用ROWLOCK,但使用它最安全)readpass
将防止进程被阻塞,等待另一个进程完成。您可以使用OUTPUT子句
UPDATE myTable SET flag = 1
WHERE
id = 1
AND
flag <> 1
OUTPUT DELETED.id
更新myTable集合标志=1
哪里
id=1
及
标志1
输出已删除。id
+1,我在想什么,但你回答得更快!我要补充的是,readpass
允许另一个进程不等待您解锁这一行,它可以跳过这一锁定行并继续扫描BeingProcessed=0
@KM的行-这是我一直想在博客上写的事情之一,因此在mo我的脑海中非常新鲜!总有一天我会抽空去做的!OUTPUT子句(来自另一个答案)是我最初考虑的,但是忘记了的名称。此方法是否比该子句提供了一些好处,或者该子句只是复制了您在此处构建的内容?@rwmnau-主要区别在于此答案允许您在事务中进行更多处理-但是,如果您不需要在事务中执行任何其他操作,那么如果您使用的是SQL Server 2005或更高版本(我想您是这样的!)