1

私はマルチスレッドコンソールアプリケーションを使用しています.各スレッドは基本的に、特定の基準が満たされたTOP 1の「ファイル」行を取得しようとし、それをロックします.(これが発生すると入力されるLockID列があり、次のスレッド次に利用可能な「ロック解除された」「ファイル」行を選択します)

SQL Server DB にモニターを配置し、2 つのクエリでデッドロックが発生するたびに。

SELECT TOP 1 F.Id, F.ContentTypeId, F.ManufacturerId, F.DocumentTypeId, F.Name, F.Description, F.VersionId, F.LastChangedVersionOn, F.ReferenceCount, F.LastChangedReferencesOn, F.LastChangedImageOn, F.ImageSize, F.IsStale, F.InvalidFile, CT.Id, CT.Name, CT.MimeType, CT.IsMimeAttachment, CT.Extensions, CT.CanTrackVersions, CT.UseRemoteSource, CT.FullTextFilter, CT.ContentHandler, V.Id, V.Size, V.Hash, V.Title, DT.Id, DT.Code, DT.Ordinal, DT.Name, DT.PluralName, DT.UrlPart
FROM Docs.Files F
INNER JOIN Docs.ContentTypes CT ON CT.Id = F.ContentTypeId
LEFT JOIN Docs.Versions V ON V.Id = F.VersionId
LEFT JOIN Docs.DocumentTypes DT ON DT.Id = F.DocumentTypeId
WHERE (F.LockId IS NULL OR F.LockedOn < DATEADD(hh,-1,GETUTCDATE()))
AND F.IsStale = 1 AND F.InvalidFile = 0 

(@Id int)UPDATE Docs.Files
SET LastChangedImageOn = GETUTCDATE(), ImageSize = (
    SELECT DATALENGTH(FileImage)
    FROM Docs.FileImages
    WHERE FileId = @Id)
WHERE Id = @Id;
SELECT TOP 1 LastChangedImageOn FROM Docs.Files WHERE Id = @Id    

最初のクエリは、新しいスレッドが作成されたときに実行され、新しい「ファイル」行を取得しようとします。

2 番目のクエリは、スレッド (以前に作成されたものである可能性があります) が「ファイル」レコードの処理をほぼ完了したときに実行されます。このクエリで使用されたトランザクション。分離レベルは「ReadCommitted」でした。2 つのスレッドが同じ「FileID」を後で処理することはないため、両方のクエリが同じ「FileID」にアクセスしようとしていないことは確かです。この問題をどのように診断できるかについて、私はひどく混乱しています。これら 2 つのクエリ間のデッドロックの原因は何ですか? 誰かが私を正しい方向に導くことができれば、本当に感謝しています。事前にどうもありがとう:)

4

1 に答える 1

1

うーん... SQL Server で何かをしたのは久しぶりです。しかし、試してみましょう。

「2 つのスレッドが同じ「FileID」をその後処理することは決してない」と述べていますが、どうすればこれを確認できますか? ID はスレッド外のソースから供給されていますか?

于 2012-08-29T19:38:05.257 に答える