質問

んなに簡単なキューの実施、MS Sql Server2008R2.こちらessenseキューの:

CREATE TABLE ToBeProcessed 
(
    Id BIGINT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Priority] INT DEFAULT(100) NOT NULL,
    IsBeingProcessed BIT default (0) NOT NULL,
    SomeData nvarchar(MAX) NOT null
)

したい原子を選択のための行を優先的に取り組み、idがIsBeingProcessedがfalseの場合は、更新者の行かれ、処理されます。ながらよく集めたものだと思うの組み合わせを使用の更新、トップス、出力によっては残念ながら使用できませんのトップによっては更新されます。

いった項を制限する更新がサブクエリは注文します(下記参照)。私の質問は、この全体算書の原子、またはいラップです。

DECLARE @numberToProcess INT = 2

CREATE TABLE #IdsToProcess
(
    Id BIGINT NOT null
)

UPDATE 
    ToBeProcessed
SET
    ToBeProcessed.IsBeingProcessed = 1
OUTPUT 
    INSERTED.Id 
INTO
    #IdsToProcess   
WHERE
    ToBeProcessed.Id IN 
    (
        SELECT TOP(@numberToProcess) 
            ToBeProcessed.Id 
        FROM 
            ToBeProcessed 
        WHERE
            ToBeProcessed.IsBeingProcessed = 0
        ORDER BY 
            ToBeProcessed.Id, 
            ToBeProcessed.Priority DESC)

SELECT 
    *
FROM 
    #IdsToProcess

DROP TABLE #IdsToProcess

こちらは一部のsqlを挿入する一部のダミーの列:

INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
役に立ちましたか?

解決

理解している意欲"という質問に対している可能性を避けるためのものとの兼取引があるのかを実行し、サブクエリを取得し、上位の行プロセスへの更新を同行?

その場合はいいのに使用します。

;WITH cte As
(
SELECT TOP(@numberToProcess) 
            *
        FROM 
            ToBeProcessed WITH(UPDLOCK,ROWLOCK,READPAST) 
        WHERE
            ToBeProcessed.IsBeingProcessed = 0
        ORDER BY 
            ToBeProcessed.Id, 
            ToBeProcessed.Priority DESC
)            
UPDATE 
    cte
SET
    IsBeingProcessed = 1
OUTPUT 
    INSERTED.Id 
INTO
    #IdsToProcess  

少しありましたが不確かな前か否かのSQLサーバーか U ロック処理時にバージョンのサブクエリをこのようにブロック二つの兼任取引から読み同 TOP N されています。この表示されません。

テストテーブル

CREATE TABLE JobsToProcess
(
priority INT IDENTITY(1,1),
isprocessed BIT ,
number INT
)

INSERT INTO JobsToProcess
SELECT TOP (1000000) 0,0
FROM master..spt_values v1, master..spt_values v2

テストスクリプト実行するとき2で同時SSMSセッション)

BEGIN TRY
DECLARE @FinishedMessage VARBINARY (128) = CAST('TestFinished' AS  VARBINARY (128))
DECLARE @SynchMessage VARBINARY (128) = CAST('TestSynchronising' AS  VARBINARY (128))
SET CONTEXT_INFO @SynchMessage

DECLARE @OtherSpid int

WHILE(@OtherSpid IS NULL)
SELECT @OtherSpid=spid 
FROM sys.sysprocesses 
WHERE context_info=@SynchMessage and spid<>@@SPID

SELECT @OtherSpid


DECLARE @increment INT = @@spid
DECLARE @number INT = @increment

WHILE (@number = @increment AND NOT EXISTS(SELECT * FROM sys.sysprocesses WHERE context_info=@FinishedMessage))
UPDATE JobsToProcess 
SET @number=number +=@increment,isprocessed=1
WHERE priority = (SELECT TOP 1 priority 
                   FROM JobsToProcess 
                   WHERE isprocessed=0 
                   ORDER BY priority DESC)

SELECT * 
FROM JobsToProcess 
WHERE number not in (0,@OtherSpid,@@spid)
SET CONTEXT_INFO @FinishedMessage
END TRY
BEGIN CATCH
SET CONTEXT_INFO @FinishedMessage
SELECT ERROR_MESSAGE(), ERROR_NUMBER()
END CATCH

ほぼ直ちに執行停止の両方を兼取引の更新と同じ行の S ロックを取りながら特定の TOP 1 priority だ発売前で、aquires U ロックその2取引を進めを行 UX ロッククラスです。

Heap

場合のCIを追加 ALTER TABLE JobsToProcess ADD PRIMARY KEY CLUSTERED (priority) その行き詰まりが発生し、その後の急速なことを行 S ロックがない、取引aquires、 U ロックを連続待ちに変換す X ロックのその他の取引を待って変換 S ロックへ U ロックが解除されます。

Clustered Index

場合、上記のクエリーの変更を使用 MINTOP

WHERE priority = (SELECT MIN(priority)
                   FROM JobsToProcess 
                   WHERE isprocessed=0 
                   )

そしてまさにSQLサーバーの管理を完全に廃絶するためにサブクエリからのプランから U ロックでよく知られるようになった

enter image description here

他のヒント

個人のT-SQLによると、すべての私の経験は、すべてのdocumenationっ読み取る原子.いがT-SQL文が,エルゴでは原子や不要な明示的な取引に関す私はこのような精密なロジックのくしかないため問題です。で見られることを楽しみにして場としてサポート可能交互に意見を出しました。

なお、このランキング機能は、具体的にはrow_number()は、取得する定数です。構文はうぽくものの、全体的な柔軟性と強力なツールです。(あるbazillionスタックOverlow質問に答えて忘れないようにしてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top