SET TRANSACTION ISOLATION LEVEL READ 미 확약의 장점


12

나는 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED대부분의 일반 SQL 쿼리에서 주로 사용합니다. 주로 원래 언어를 배울 때 나에게 훈련 되었기 때문입니다.

내 이해에서이 격리 수준은 WITH (NO LOCK)내가 사용하는 경향이 있는 것과 같은 방식으로 작동합니다 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • 내가 사용해야하는 시간이 적 있습니까 WITH (NO LOCK)이상은 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • 합니까 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED내가 읽는 오전 테이블의 잠기기에서 정지 다른 사용자?
  • 경우 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED정지 잠금 장치에 사용되는,하지만 난 단지 데이터를 읽고있다, 그것을 사용의 점은 무엇인가? 잠금을 생성하는 것은 시스템 집약적 인 쿼리입니까? 5-10 초로 반환되는 쿼리를 실행할 때 사용할 가치가 있습니까?
  • 나는 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED아마도 더러운 데이터를 업데이트하지 않기 위해 업데이트에 사용될 데이터를 읽을 때 사용하지 말라고 들었습니다 . 이것이 유일한 이유일까요?
  • 작업중인 데이터베이스 유형에는 프로덕션 및 테스트 환경이 있습니다. 프로덕션 환경을 쿼리하는 경우는 거의 없지만 필요할 때 일반적으로 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED쿼리에 사용 합니다. 나는 더티 읽기가 가능하다는 것을 이해합니다. 데이터베이스에 커밋되지 않아서 결과를 버릴 수없는 데이터를 다시받는 것 외에도 다른 유형의 '더러운 읽기'가 가능합니까?

대량 질문에 대해 죄송합니다.


2
같은 데이터를 두 번 읽을 수 있다는 것은 또 다른 함정입니다. RU 또는 NO LOCK을 표준으로 사용하는 것은 좋지 않습니다.
제임스 앤더슨

9
나는 READ UNCOMMITTED어디에서나 사용하지 않을 때 와 똑같은 방식으로 WITH (NOLOCK)어디에서나 사용하지 않을 것입니다 ( 블로그
Mark Sinkinson

1
SNAPSHOT 격리 모델을 살펴보십시오. RCU보다 훨씬 강력하며 차단하거나 차단하지 않습니다. RCU로 기본 설정하는 대신 기본 모델처럼 들립니다.
usr

답변:


25

그런 식으로 배운 것은 끔찍합니다 (죄송합니다!).

READ UNCOMMITTED모든 행을 읽겠습니다. 예. 심지어 현재에 사용되는 사람 INSERT, UPDATE, DELETE운영. 이것은 일부 데이터를 살펴 보거나 SELECT블록이 매우 유해한 미션 크리티컬 한 진술을 볼 때 매우 유용합니다 .

실제로, 당신은 당신의 충절의 위험이 있습니다. 현재 삭제 또는 변경에 사용 된 행을 읽을 수 있습니다. 잘못된 값을 읽은 것으로 나타날 수도 있습니다. 이것은 흔하지는 않지만 일어날 수 있습니다. 그게 무슨 뜻이야? 글쎄, 매우 넓은 행을 생각하십시오 (긴 nvarchar열 이 많은 열이 많이 있습니다 ). 이 행에서 업데이트가 발생하고 새 값을 설정합니다. 드문 경우지만 절반 행만 읽는 것이 발생할 수 있습니다. 예를 들어, 사용자가 로그인 값을 변경하면 다른 일이 발생할 수 있습니다. 그는 메일 + 비밀번호를 변경합니다. 메일이 이미 설정되어 있지만 비밀번호가 설정되어 있지 않습니다. 이렇게하면 일관성이없는 상태가됩니다.

나는 잊어 버리는 것이 좋습니다 READ UNCOMMITTED. 실제로 필요한 곳에 사용하십시오 .

또 다른 대안은 READ_COMMITTED_SNAPSHOT데이터베이스 옵션 을 활성화하는 것 READ COMMITTED SNAPSHOT입니다. tempdb에서 활성화 된 행 버전 관리로 인해 사용할 수 있습니다 . 이렇게하면 다른 (이전) 버전의 행을 읽을 수 있습니다. 검색어를 차단하지 않습니다. 그러나 이전 값도 읽지 만 일관된 이전 값을 읽을 수 있습니다.

WITH(READPAST)대신 다른 아이디어를 사용할 수 있습니다 WITH(NOLOCK). 테이블의 이전 상태를 읽지 만 (와 약간 비슷 함 SNAPSHOT ISOLATION) 대신 현재 잠긴 행을 모두 건너 뜁니다.


@Ionic, 답변 주셔서 대단히 감사합니다! 도움을 주셔서 감사합니다.
dmoney

@HingeSight, 그것은 들리는 것처럼 들리지만, 당신의 의견에 대해 감사의 말을 전했을 것입니다.
dmoney

1
SNAPSHOT ISOLATION전원을 켜기 위해 활성화 할 필요는 없습니다 READ COMMITTED SNAPSHOT. READ COMMITTED SNAPSHOT읽기 일관성을 위해 잠금 대신 행 버전 관리를 수행하여 더티 읽기를 피할 수 있도록 데이터베이스 옵션 만 활성화해야합니다.
Dan Guzman

네, @ DanGuzman을 의미했습니다. 그 시점에서 대답이 약간 불명확했습니다. 편집했습니다. :-)
Ionic

READPAST를 사용하면 잠긴 레코드를 건너 뛰고 이전 값을 얻지 못하므로 사용할 수 있다고 생각한 유일한 곳은 대기열 처리입니다.
James Z

2

허용되는 답변에 따르면 잘못된 데이터를 읽을 위험이 있으므로 READ UNCOMMITTED 격리 수준 (실제로 필요한 경우 제외)을 사용하는 것을 잊지 마십시오. 그러나 귀하의 질문에서 세 번째 글 머리 기호에 답하기 위해 두 가지 상황이 유용하다고 생각합니다.

  1. SQL Server SSIS 패키지를 작성하고 테스트 할 때 패키지 단계가 트랜잭션으로 래핑 될 수 있습니다. SSIS 디버거에서 단계별로 패키지를 실행하여 패키지를 테스트하는 경우 테이블에 잠금이있는 동안 테이블을 검사 할 수 있습니다. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED를 사용하면 패키지가 디버깅되는 동안 SQL Server Manager Studio를 사용하여 테이블을 검사 할 수 있습니다.

  2. SQL Server Manager Studio에서는 T-SQL 코드를 트랜잭션에 래핑하여 변경 사항을 롤백 할 수있는 옵션을 제공하여 테스트 할 수 있습니다. 예를 들어 테스트 데이터베이스에서 테스트의 일부로 데이터를 초기 상태로 복원 할 수 있습니다. 트랜잭션 랩핑 된 코드를 테스트하고 트랜잭션이 진행되는 동안 잠긴 테이블을 확인하려는 경우 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED를 사용하여 다른 창에서 값을 검사 할 수 있습니다.

나는 이것이 커밋되지 않은 읽기에 대해 상당히 모호한 용도라는 것을 인정하지만 테스트 환경에서 유용하다는 것을 알았습니다.


1

대부분의 데이터베이스에서 삽입, 삭제 및 업데이트 등 대부분의 활동은 명시 적 트랜잭션 외부에 있습니다.

물론, READ UNCOMMITTED(Dirty Reads)는이 경우 잘못된 정보를 제공 할 수 있지만 해당 정보는 5 초 전에 수정되었습니다.

Dirty Reads가 실제로 나쁜 결과를 생성하는 시간은 트랜잭션이 실패하여 롤백해야하거나 명시 적 트랜잭션을 사용하여 일반적으로 함께 업데이트되는 두 테이블에 대해 쿼리를 실행할 때입니다.

한편 읽기 대 쓰기 비율이 100 (또는 1) 이상인 일반적인 대규모의 사용량이 많은 데이터베이스에서 Dirty Reads를 사용하지 않는 모든 단일 (읽기) 쿼리는 시스템을 확보하고 확인해야하므로 시스템 속도가 느려집니다. 잠금의 경우 트랜잭션이 실패 할 가능성이 높아지고 (보통 교착 상태로 인해) 데이터베이스 무결성 문제가 더 심각해질 수 있습니다.

대신 더티 읽기를 사용하면 시스템 MUCH가 더 빠르고 안정적으로 만들어집니다 (일부 성능 향상으로 인해 불일치가 덜 발생 함).

물론, 사용해서는 안될 때가 있습니다. SQL 스크립트 및 SP 시작시 READ UNCOMMITTED격리 수준 을 사용 하거나 명시 적 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED문 을 사용하도록 데이터베이스를 기본값으로 설정하는 것을 좋아하지 않습니다. Dirty Read가 발생하지 않아야 할 때 너무 많이 읽을 가능성이 너무 많습니다. 대신 (NOLOCK)힌트는 프로그래머가 자신이하는 일에 대해 생각하고이 특정 쿼리의 특정 테이블에 대해 Dirty Reads가 안전하다고 결정했음을 명시 적으로 나타 내기 때문에 훨씬 더 나은 접근 방법입니다.

한 은행 계좌에서 다른 은행 계좌로 돈을 이체하도록 애플리케이션을 프로그래밍하는 경우 Dirty Reads를 사용하지 않아야합니다. 그러나 대부분의 응용 프로그램에는 편집증 수준이 필요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.