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

时间:2010-08-04 00:00:30

标签: sql-server transactions serializable

编辑:SQL Server 2005

我有一个在5个独立服务器上运行的客户应用程序。每个应用程序都在查看单个调度表。我想确保没有任何机器可以与任何其他机器同时访问同一条记录。每个服务器一次只能处理1行。基本上,应用程序只选择可以运行的下一条可用记录。如果没有选择任何内容,它就什么也不做,等待另一分钟再试一次。

[编辑:更具体地说,从dbo.the_table中永远不会删除任何行。它只是标记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语句都将被阻止,直到阻塞事务提交事务为止。 (例如,机器A启动一个事务 - 如果B,C,D或E尝试和SELECT,它们将等待事务提交。)

1 个答案:

答案 0 :(得分:4)

您使用的是哪个版本的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*/