2012-04-11 9 views
1

のシェアをしてみましょう私は、開発者が自分のロック機構を実装していますが、私にはそれが欠陥のあるように見えたSPROCを維持しています:SPROCプロセスの実行ごとに行

CREATE PROCEDURE Sproc 1 
AS 

Update X 
set flag = lockedforprocessing 
where flag = unprocessed 

-- Some processing occurs here with enough time to 
-- 1. table X gets inserted new rows with a flag of unprocessed 
-- 2. start another instance of this Sproc 1 that executes the above update 

Select from X 
where flag = lockedforprocessing 

-- Now the above statement reads rows that it hadn't put a lock on to start with. 

私はちょうどそれを包むことができることを知っているがSERIALIZABLEの分離レベルのトランザクション内でsprocを使用していますが、私はこれを避けたいと考えています。

目標は、このSPROCの複数のインスタンスを同時に実行し、最大同時実行を実現するために、レコードの独自の「シェア」を処理することができます

  1. です。
  2. SPROCをの実行は、まだ私はそれが未処理「の値を持つ新しいレコードを防ぐことはできませんので、REPEATABLE READはここに助けることができるとは思わない

を実行している前回の実行を待つべきではありません"読まれている(私が間違っていたら私を修正してください)。

私はsp_getlock sprocを発見しましたが、それはバグを解決しますが、私の目標ではないexactionをシリアライズします。

私が見ている解決策は、procを実行するたびに独自のGUIDを生成し、それをフラグに割り当てることですが、何とかSQL Serverが既に解決できる何かをシミュレートしていると思っています。

SERIALIZABLEで行を共有するsprocプロセスを実行する唯一の方法はありますか?

よろしく、トムXでのIDフィールドがあると仮定すると、

+0

ひとつをHTTP([キューとしてテーブルを使用する]に:/stackoverflow.com/questions/4686726/sql-server-using-a-table-as-a-queue)あなたを助けるかもしれません。 – AakashM

答えて

0

は、更新されたXの一時テーブルを助けることができる:答えの

CREATE PROCEDURE Sproc 1 
AS 
-- Temporary table listing all accessed Xs 
    declare @flagged table (ID int primary key) 
-- Lock and retrieve locked records 
    Update X 
     set flag = lockedforprocessing 
    output Inserted.ID into @flagged 
    where flag = unprocessed 

-- Processing 
    Select from X inner join @flagged f on x.ID = f.ID 

-- Clean-up 
    update X 
     set flag = processed 
    from x inner join @flagged f on x.ID = f.ID 
+0

非常に洗練されたソリューション。私は私のprodのSQL Serverは、それが後のSQL Serverのバージョンの一部で導入されたように出力をサポートすることを願っていますAFAIK – buckley

+0

@buckley 2005年に導入されました。 –

関連する問題