각 스레드는 기본적으로 특정 조건을 만족하는 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
첫 번째 쿼리
는 새로운 스레드가 생성 될 때 실행하고 우리는 새로운 '파일'행을 얻으려고한다.두 번째 쿼리는 스레드 (이전에 생성 된 스레드 일 수 있음)가 '파일'레코드 처리를 거의 완료하면 실행됩니다.이 쿼리에서 사용 된 트랜잭션. 격리 수준은 "ReadCommitted"입니다. 두 개의 스레드가 동일한 "FileID"를 처리하지 않기 때문에 두 쿼리가 모두 동일한 "FileID"에 액세스하려고 시도하지 않았 음을 확신합니다. 나는이 문제를 어떻게 진단 할 수 있는지 몹시 혼란 스럽다. 이 두 쿼리 사이에 교착 상태가 발생했을 수 있습니다. 누군가가 나를 올바른 방향으로 안내 할 수 있다면 정말 고맙겠습니다. 미리 감사드립니다 :)
자세한 정보가 있으면 도움이됩니다. - 어떤 데이터베이스 서버 및 엔진 (사용 가능한 경우)을 사용하고 있습니까? - 거래를 사용하고 있습니까? 추신 SQL은 구조화 조회 언어의 약자입니다. SQL을 사용하는 많은 DB가 있습니다. – Paul
격리 수준은 무엇입니까? –
또한, 내가 볼 수있는 유일한 경합은 Docs.Files에 있습니다 - 아마도 읽기와 쓰기가 혼란 스러울 수 있습니다 ... 옵션 : 읽기 작업을 적은 (제로) 격리로 만들어 읽기 잠금을 수행하지 않습니다 ; 또는 read * more *를 분리시켜 쓰기 잠금 (데드락보다는 블로킹)을 취하도록하십시오. 어느 쪽이 바람직합니까? –