2011-12-09 135 views
0

我有一些文件处理功能,它使用数据库表来确定文件是否已被处理。SQL Server - 锁定/阻止方案

IF EXISTS (SELECT * FROM FileTable WITH (UPDLOCK, ROWLOCK, HOLDLOCK) 
      WHERE FileName = @FileToProcess) 
BEGIN 
    -- File already processed. 
END 
ELSE 
BEGIN 
    -- Process file. 
END 

我想要的行为如下: -

  • 只有一个交易应以一次处理一个文件。
  • 同时处理不同的文件。
  • 如果在处理同一文件时尝试处理同一个文件,那么该事务将阻塞,直到另一个文件结束。

我非常确定这是可能的,但是我的SQL锁定知识并不完美!到目前为止,我的尝试要么在上面的示例中包含锁定提示,这会导致子弹点2失败。我尝试过的所有其他锁定提示都导致子弹点3失败。

我错过了什么?

+0

[SQL的可能重复服务器进程队列争用条件](http://stackoverflow.com/questions/939831/sql-server-process-queue-race-condition) – gbn

回答

0

尝试增加READPAST允许2点

你可能会在this article

+0

不幸的是,READPAST提示不能与HOLDLOCK提示一起使用,如果我删除HOLDLOCK提示它突破第3点。 – user1085351

+0

优秀的文章。你可能想在你的回答中更多地宣传它。 :) – 2011-12-09 11:48:03

2

我已经回答过类似的问题感兴趣:SQL Server Process Queue Race Condition。总之,您需要ROWLOCK, READPAST, UPDLOCK提示将表格用作队列。

但是,您无法使用数据库引擎锁“阻止”相同的文件,因为这意味着在处理文件时保持事务处于打开状态。你可以做的是“国旗”,因此它被其他进程在安全并行的方式跳过按我上面的链接

文件,我其他的答案也可以帮助你https://stackoverflow.com/search?tab=votes&q=user%3a27535%20readpast

+0

我尝试过使用这些提示,但是当我这样做的时候它突破了第3点。 – user1085351

+0

请参阅我的第2段:您希望的模式通常是某些客户端代码将调用数据库,获取有关处理内容,处理它的信息以及回写。你不保持交易的开放 – gbn