Sql server 适用于此场景的可序列化事务?

Sql server 适用于此场景的可序列化事务?,sql-server,transactions,serializable,Sql Server,Transactions,Serializable,编辑:SQL Server 2005 我有一个客户应用程序在5个独立的服务器上运行。每个应用程序都在查看单个调度表。我想确保没有一台机器可以像其他机器一样同时访问同一条记录。每台服务器一次只能处理一行。基本上,应用程序只是选择下一条可以运行的可用记录。如果未选择任何内容,它将不执行任何操作,然后再等待一分钟,然后重试 [编辑:更具体地说,从未从dbo.the_表中删除任何行。它只是将IsProcessing=1标记,以便其他机器不会拾取该行] 我的存储过程SQL Server如下所示: SET

编辑:SQL Server 2005

我有一个客户应用程序在5个独立的服务器上运行。每个应用程序都在查看单个调度表。我想确保没有一台机器可以像其他机器一样同时访问同一条记录。每台服务器一次只能处理一行。基本上,应用程序只是选择下一条可以运行的可用记录。如果未选择任何内容,它将不执行任何操作,然后再等待一分钟,然后重试

[编辑:更具体地说,从未从dbo.the_表中删除任何行。它只是将IsProcessing=1标记,以便其他机器不会拾取该行]

我的存储过程SQL Server如下所示:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

SET @ScheduleId = SELECT TOP 1 ScheduleId FROM dbo.the_table WHERE NextRun <= GETDATE() AND IsEnabled = 1

UPDATE dbo.the_table SET IsProcessing=1 WHERE ScheduleId = @ScheduleId

--Edit: Return this to the program so we can do stuff with the data
SELECT * FROM dbo.the_table WHERE ScheduleId = @ScheduleId

IF @@ERROR = 0
COMMIT TRAN
ELSE
ROLLBACK TRAN

我想确定,当事务正在进行时,其他机器的任何SELECT语句都将被阻塞,直到阻塞事务提交该事务为止。e、 例如,机器A启动事务-如果B、C、D或e尝试并选择,它们将等待事务提交。

您使用的是哪个版本的SQL Server?如果SQL2005+您可以在一条语句中完成这一切

;WITH s AS
(
SELECT TOP 1 * 
FROM dbo.the_table WHERE NextRun <= GETDATE() AND IsEnabled = 1
AND IsProcessing = 0 /*?*/
--ORDER BY ScheduleId  ?
)
UPDATE    s  WITH (ROWLOCK, READPAST)
SET     IsProcessing=1 
OUTPUT INSERTED.*  /*Return row that was updated*/

+1此外,我建议您检查一下,因为本例中的_表用作队列。非常抱歉。我错过了手术的一个重要环节。我已经做了适当的编辑。@Remus,谢谢非常有用的链接@零-据我所知,返回INSERTED.*并让选择行的过程检查IsProcessing=0可以很容易地适应这一点-或者我遗漏了什么?我只是想确保通过编辑,您的解决方案仍然可行,因为我不是SQL Server专家。听起来你的解决方案会起作用-我还需要包括设置事务隔离级别SERIALIZABLE并添加我的BEGIN TRAN/COMMIT TRAN吗?@Zero-不,你不需要这些。不管怎样,它只是隐式事务中的一条语句,请参阅Remus的链接,了解LCK_M_锁定的解释以及不需要更改隔离级别的原因。