我的(简化的)表由一个
Id int identity(1,1),
File varchar(20),
FileProcessed bit
逻辑是这样的:我的应用程序获取第一条记录(顺序不重要),该记录的FileProcessed位设置为false。然后,它处理文件并将FileProcessed位设置为true。
现在,可能发生的情况是,第一个线程使用ID为1的记录,而在处理它时,另一个线程使用ID为1的记录(因为它不在市场上被处理)。
在此示例中,支持多线程的最佳方法是什么?
编辑:我使用SQL Sever 2005
EDIT2:文件的处理可能需要很长时间,因此我不想同时锁定整个表
最佳答案
其他人提到添加一个额外的列-您也可以考虑将FileProcessed列更改为一个名为e.g.的列。状态-您可以在何处建模“未处理”,“正在处理”,“已处理”,“故障”? (例如,如果无法处理该文件会发生什么情况)。
另外,如果处理失败,是否要立即重试处理文件。如果处理器意外死机,您将如何处理(例如,您可能需要另一个表来描述每次处理尝试的开始时间-如果最后一次尝试是在20分钟前开始的(或任何合理的方法),那么您可能会认为失败的尝试。
为了正确进行选择/更新,您可能需要类似以下的脚本:
declare @FileID int
BEGIN TRANSACTION
select top 1 @FileID = FileID from FilesToDoStuffTo with (updlock,holdlock,readpast) where Status=Unprocessed
update FilesToDoStuffTo set Status = Processing where FileID = @FileID
COMMIT
然后,对您选择的@FileID做任何您需要做的事情。