Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 获得;“下一步”;SQL Server数据库中的行,并在单个事务中标记它_Sql Server_Tsql_Transactions_Queue - Fatal编程技术网

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

我有一个SQL Server表,用作队列,它由一个多线程(即将成为多服务器)应用程序处理。我想让一个进程声明队列中的下一行,将其标记为“进程内”,而不允许多个线程(或多个服务器)同时声明同一行

是否有方法更新行中的标志并同时检索该行?我想要这样的伪代码,但理想情况下,不阻塞整个表:

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或更高版本(我想您是这样的!)