T-SQLサブクエリ、更新制限原子、アップグレードしてみた。
-
28-09-2019 - |
質問
んなに簡単なキューの実施、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取引を進めを行 U
や X
ロッククラスです。
場合のCIを追加 ALTER TABLE JobsToProcess ADD PRIMARY KEY CLUSTERED (priority)
その行き詰まりが発生し、その後の急速なことを行 S
ロックがない、取引aquires、 U
ロックを連続待ちに変換す X
ロックのその他の取引を待って変換 S
ロックへ U
ロックが解除されます。
場合、上記のクエリーの変更を使用 MIN
よ TOP
WHERE priority = (SELECT MIN(priority)
FROM JobsToProcess
WHERE isprocessed=0
)
そしてまさにSQLサーバーの管理を完全に廃絶するためにサブクエリからのプランから U
ロックでよく知られるようになった
他のヒント
個人のT-SQLによると、すべての私の経験は、すべてのdocumenationっ読み取る原子.いがT-SQL文が,エルゴでは原子や不要な明示的な取引に関す私はこのような精密なロジックのくしかないため問題です。で見られることを楽しみにして場としてサポート可能交互に意見を出しました。
なお、このランキング機能は、具体的にはrow_number()は、取得する定数です。構文はうぽくものの、全体的な柔軟性と強力なツールです。(あるbazillionスタックOverlow質問に答えて忘れないようにしてください。