UPDLOCK, HOLDLOCK에 대해 혼동됨
표 힌트를 사용하는 방법을 연구하던 중 다음 두 가지 질문을 발견했습니다.
두 가지 질문에 대한 대답은 다음과 같습니다.(UPDLOCK, HOLDLOCK)
다른 프로세스에서는 해당 테이블의 데이터를 읽을 수 없습니다. 하지만 저는 이것을 보지 못했습니다.테스트를 위해 테이블을 만들고 두 개의 SSMS 창을 시작했습니다.첫 번째 창에서 다양한 테이블 힌트를 사용하여 테이블에서 선택한 트랜잭션을 실행했습니다.트랜잭션이 실행되는 동안 두 번째 창에서 여러 가지 문을 실행하여 어떤 문이 차단되는지 확인했습니다.
테스트 테이블:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SSMS 창 1에서:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
SSMS 창 2(다음 중 하나를 실행)에서:
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
창 2에서 실행되는 문에 대한 여러 테이블 힌트의 영향:
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
제가 그 질문들의 답을 잘못 이해했나요, 아니면 제 시험에서 실수했나요? 않다면 왜 만약그않면, 왜당은신을 합니까?(UPDLOCK, HOLDLOCK)
대 대(HOLDLOCK)
혼자?
제가 달성하고자 하는 목표에 대한 추가 설명:
테이블에서 행을 선택하고 테이블을 처리하는 동안 해당 테이블의 데이터가 수정되지 않도록 합니다.해당 데이터를 수정하지 않고 읽기를 허용합니다.
이 대답은 분명히 말합니다.(UPDLOCK, HOLDLOCK)
읽기를 차단합니다(내가 원하는 것이 아님).이 답변에 대한 의견은 다음과 같이 암시합니다.HOLDLOCK
읽기를 방지합니다.표의 효과를 더 잘 이해하고 있는지 확인하기 위해 노력합니다.UPDLOCK
혼자서 제가 원하는 것을 할 수 있었고, 저는 위의 실험을 했고 그 답들과 상반되는 결과를 얻었습니다.
현재, 저는 그것을 믿습니다.(HOLDLOCK)
제가 써야 할 것인데 제가 실수를 했거나 나중에 저를 물어뜯을 것을 간과한 것은 아닌지 걱정이 되기 때문에 이 질문을 하게 됩니다.
UPDLOCK 블록이 선택되는 이유는 무엇입니까?잠금 호환성 매트릭스가 명확하게 표시합니다.N
S/U 및 U/S 경합의 경우(충돌 없음).
HOLD LOCK 힌트에 대해서는 문서에 다음과 같이 기술되어 있습니다.
HOLD LOCK: 시리얼화가 가능합니다.자세한 내용은 이 항목의 뒷부분에 있는 직렬화를 참조하십시오.
...
직렬화 가능: ...검색은 직렬화된 분리 수준에서 실행되는 트랜잭션과 동일한 의미로 수행됩니다.
트랜잭션 격리 수준 항목에서는 시리얼화가 의미하는 바를 설명합니다.
현재 트랜잭션이 완료될 때까지 현재 트랜잭션에서 읽은 데이터를 수정할 수 있는 다른 트랜잭션은 없습니다.
다른 트랜잭션은 현재 트랜잭션이 완료될 때까지 현재 트랜잭션의 모든 문에서 읽은 키 범위에 해당하는 키 값을 가진 새 행을 삽입할 수 없습니다.
따라서 표시된 동작은 제품 설명서에 완벽하게 설명되어 있습니다.
- UPDLOCK은 동시 SELECT 또는 INSERT를 차단하지 않지만 T1에서 선택한 행의 모든 업데이트 또는 DELETE를 차단합니다.
- HOLD LOCK은 직렬화 가능을 의미하므로 SELECT를 허용하지만 T1에서 선택한 행뿐만 아니라 T1에서 선택한 범위(전체 테이블, 즉 임의의 삽입)의 모든 삽입을 차단합니다.
- (UPDLOCK, HOLDLOCK): 위의 경우 외에 차단할 수 있는 것, 즉 T2에서 UPDLOCK과의 또 다른 트랜잭션을 보여주지 않습니다.
SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
- TABLOCKX 설명 필요 없음
진짜 문제는 당신이 무엇을 성취하려고 노력하느냐는 것입니다.잠금 힌트를 가지고 노는 것은 잠금 의미에 대한 110%의 완전한 이해 없이 문제를 구걸하는 것입니다...
작업 편집 후:
테이블에서 행을 선택하고 테이블을 처리하는 동안 해당 테이블의 데이터가 수정되지 않도록 합니다.
더 높은 트랜잭션 격리 수준 중 하나를 사용해야 합니다.반복 가능 읽기는 읽은 데이터가 수정되는 것을 방지합니다.SERIABLISABLE을 사용하면 읽은 데이터가 수정되지 않고 새 데이터가 삽입되지 않습니다.쿼리 힌트를 사용하는 것이 아니라 트랜잭션 격리 수준을 사용하는 것이 올바른 접근 방식입니다.켄드라 리틀은 격리 수준을 설명하는 멋진 포스터를 가지고 있습니다.
UPDLOCK은 이후 업데이트 문에 대한 선택 문을 실행하는 동안 행을 잠그려는 경우 사용됩니다.향후 업데이트는 트랜잭션의 다음 문장일 수 있습니다.
다른 세션에서도 데이터를 볼 수 있습니다.UPDLOCK 및/또는 HOLDLOCK과 호환되지 않는 잠금을 얻을 수 없습니다.
UPDLOCK은 다른 세션이 잠긴 행을 변경하지 못하도록 하려는 경우 사용합니다.잠긴 행을 업데이트하거나 삭제할 수 있는 기능이 제한됩니다.
다른 세션에서 보고 있는 데이터가 변경되지 않도록 하려면 HOLDLOCK을 사용합니다.사용자가 잠근 행을 삽입, 업데이트 또는 삭제할 수 있는 기능이 제한됩니다.이렇게 하면 쿼리를 다시 실행하여 동일한 결과를 볼 수 있습니다.
언급URL : https://stackoverflow.com/questions/7843733/confused-about-updlock-holdlock
'programing' 카테고리의 다른 글
C# WPF에서 내 TabControl의 SelectionChanged 이벤트가 너무 자주 실행되는 이유는 무엇입니까? (0) | 2023.04.26 |
---|---|
NSNumber를 NSString으로 변환하는 방법 (0) | 2023.04.26 |
NSDate에 1일을 추가하려면 어떻게 해야 합니까? (0) | 2023.04.26 |
Bash에서 구분 기호의 문자열을 분할하려면 어떻게 해야 합니까? (0) | 2023.04.26 |
Linux에서 디렉토리를 루프오버하는 방법 (0) | 2023.04.21 |