programing tip

TABLOCK 대 TABLOCKX

itbloger 2020. 11. 2. 07:42
반응형

TABLOCK 대 TABLOCKX


차이 무엇 TABLOCKTABLOCKX http://msdn.microsoft.com/en-us/library/ms187373.aspxTABLOCK동안 공유 잠금입니다 TABLOCKX배타적 잠금됩니다. 첫 번째는 일종의 인덱스 잠금일까요? 그리고 자물쇠 공유의 개념은 무엇입니까?


큰 차이 TABLOCK는 "공유"잠금과 TABLOCKX배타적 잠금 을 잡으려고 합니다.

트랜잭션 중이고 테이블에 대한 독점 잠금을 획득 한 경우 EG :

SELECT 1 FROM TABLE WITH (TABLOCKX)

다른 프로세스는 테이블에 대한 잠금을 확보 할 수 없습니다. 즉, 트랜잭션이 커밋 될 때까지 테이블과 통신하려는 모든 쿼리가 차단됩니다.

TABLOCK공유 잠금 만 잡고 트랜잭션 격리가 READ COMMITTED(기본값) 인 경우 명령문이 실행 된 후 공유 잠금이 해제 됩니다. 격리 수준 이 더 높은 경우 (예 SERIALIZABLE:) 공유 잠금은 트랜잭션이 끝날 때까지 유지됩니다.


공유 잠금은 공유됩니다. 의미 2 트랜잭션은 둘 다 테이블에 S 또는 IS 잠금을 보유하는 경우 (를 통해 TABLOCK) 테이블에서 동시에 데이터를 읽을 수 있습니다 . 그러나 transaction A테이블에 공유 잠금을 보유하는 경우 transaction B모든 공유 잠금이 해제 될 때까지 독점 잠금을 확보 할 수 없습니다. msdn에서 어떤 잠금과 호환되는지 읽어보십시오 .


두 힌트 모두 db가 행 또는 페이지 수준 잠금과 같은보다 세분화 된 잠금을 사용하지 않도록합니다. 원칙적으로 더 세분화 된 잠금은 더 나은 동시성을 허용합니다. 예를 들어, 하나의 트랜잭션이 두 트랜잭션에서 동시에 테이블의 100 행과 1000 행을 업데이트 할 수 있습니다 (페이지 잠금으로 인해 까다로워 지지만 건너 뛸 수 있음).

일반적으로 세분화 된 잠금이 원하는 것이지만 때로는 특정 작업의 성능을 높이고 교착 상태의 가능성을 제거하기 위해 db 동시성을 줄일 수 있습니다.

일반적으로 사용 하지 TABLOCK않거나 TABLOCKX일부 엣지 케이스에 절대적으로 필요하지 않은 경우.


mssqlcity에 대한 꽤 오래된 기사 는 잠금 유형을 설명하려고 시도합니다.

공유 잠금은 SELECT 문과 같이 데이터를 변경하거나 업데이트하지 않는 작업에 사용됩니다.

업데이트 잠금은 SQL Server가 페이지를 수정하려고 할 때 사용되며 나중에 실제로 변경하기 전에 업데이트 페이지 잠금을 배타적 페이지 잠금으로 승격합니다.

독점 잠금은 UPDATE, INSERT 또는 DELETE와 같은 데이터 수정 작업에 사용됩니다.

논의되지 않는 것은 의도 (기본적으로 이러한 잠금 유형의 수정 자)입니다. 의도 (공유 / 독점) 잠금은 실제 잠금보다 높은 수준에서 보유 된 잠금입니다. 따라서 예를 들어 트랜잭션에 행에 대한 X 잠금이있는 경우 테이블 수준에서도 IX 잠금을 갖게됩니다 (다른 트랜잭션이 테이블의 상위 수준에서 호환되지 않는 잠금을 획득하지 못하도록 차단합니다 (예 : 스키마). 수정 잠금) 트랜잭션이 완료되거나 롤백 될 때까지).


잠금을 "공유"하는 개념은 매우 간단합니다. 여러 트랜잭션이 동일한 리소스에 대해 공유 잠금을 가질 수있는 반면, 단일 트랜잭션에만 독점 잠금이있을 수 있으며, 독점 잠금은 모든 트랜잭션이 공유 잠금을 얻거나 보유하는 것을 차단합니다.


이것은 TABLOCK이 나를 위해 작동하지 않았고 TABLOCKX가 작동했던 예에 더 가깝습니다.

두 세션이 있는데 둘 다 기본 (READ COMMITTED) 격리 수준을 사용합니다.

세션 1은 연결된 서버에서 데이터베이스의 테이블 집합으로 데이터를 복사하는 명시 적 트랜잭션이며 실행하는 데 몇 초가 걸립니다. [예시, 질문 삭제] 세션 2는 세션 1이 변경하지 않는 테이블에 행을 삽입하는 삽입 문입니다. [예시 답변 삽입].

(실제로는 세션 1이 트랜잭션을 실행하는 동안 동시에 여러 레코드를 테이블에 삽입하는 여러 세션이 있습니다.)

세션 1은 세션 2에 의해 추가 된 항목에 종속 된 레코드를 삭제할 수 없기 때문에 세션 2가 삽입 한 테이블을 쿼리해야합니다. [예 : 답변되지 않은 질문 삭제].

따라서 세션 1이 실행되고 세션 2가 삽입을 시도하는 동안 세션 2는 매번 교착 상태가됩니다.

따라서 세션 1의 삭제 문은 다음과 같습니다. DELETE tblA FROM tblQ LEFT JOIN tblX on ... LEFT JOIN tblA a ON tblQ.Qid = tblA.Qid WHERE ... a.QId IS NULL and ...

교착 상태는 세션 2, [3, 4, 5, ..., n]이 tblA에 삽입을 시도하는 동안 tblA 쿼리 간의 경합으로 인해 발생한 것으로 보입니다.

제 경우에는 세션 1 트랜잭션의 격리 수준을 SERIALIZABLE로 변경할 수 있습니다. 내가 이것을했을 때 : 트랜잭션 관리자가 원격 / 네트워크 트랜잭션에 대한 지원을 비활성화했습니다.

따라서 여기에 허용 된 답변의 지침에 따라 문제를 해결할 수 있습니다. 트랜잭션 관리자가 원격 / 네트워크 트랜잭션에 대한 지원을 비활성화했습니다.

그러나 a) 처음에는 격리 수준을 SERIALIZABLE로 변경하는 것이 편하지 않았습니다. 성능이 저하되고 고려하지 않은 다른 결과가 발생할 수 있습니다. b) 이렇게하면 트랜잭션이 갑자기 발생하는 이유를 이해하지 못했습니다. 연결된 서버에서 작동하는 문제 및 c) 네트워크 액세스를 활성화하여 어떤 구멍을 열 수 있는지 알지 못합니다.

문제를 일으키는 매우 큰 트랜잭션 내에 단 6 개의 쿼리 만있는 것 같습니다.

그래서 TABLOCK과 TabLOCKX에 대해 읽었습니다.

나는 차이점에 대해 명확하지 않았고 둘 중 하나가 작동하는지 알지 못했습니다. 하지만 그럴 것 같았습니다. 먼저 TABLOCK을 시도했지만 아무런 차이가없는 것 같습니다. 경쟁 세션에서 동일한 교착 상태가 발생했습니다. 그런 다음 TABLOCKX를 시도했고 더 이상 교착 상태가 발생하지 않았습니다.

그래서 여섯 군데에서 내가해야 할 일은 WITH (TABLOCKX)를 추가하는 것뿐이었습니다.

따라서 세션 1의 삭제 문은 다음과 같습니다. DELETE tblA FROM tblQ q LEFT JOIN tblX x on ... LEFT JOIN tblA a WITH (TABLOCKX) ON tblQ.Qid = tblA.Qid WHERE ... a.QId IS NULL 및 ...

참고 URL : https://stackoverflow.com/questions/5102152/tablock-vs-tablockx

반응형