[database] 반복 불가능 읽기와 팬텀 읽기의 차이점은 무엇입니까?

반복 불가능한 읽기와 팬텀 읽기의 차이점은 무엇입니까?

WikipediaIsolation (데이터베이스 시스템) 기사를 읽었 지만 몇 가지 의심이 있습니다. 아래 예제에서 반복 불가능한 읽기팬텀 읽기 ?

거래 A

SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

산출:

1----MIKE------29019892---------5000

거래 B

UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;

거래 A

SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

또 다른 의심은 위의 예에서 어떤 격리 수준을 사용해야합니까? 그리고 왜?



답변

Wikipedia에서 (이에 대한 훌륭하고 자세한 예가 있음) :

반복 불가능한 읽기는 트랜잭션이 진행되는 동안 행이 두 번 검색되고 행 내의 값이 읽기마다 다를 때 발생합니다.

팬텀 읽기는 트랜잭션 과정에서 두 개의 동일한 쿼리가 실행되고 두 번째 쿼리에서 반환 된 행 컬렉션이 첫 번째 쿼리와 다른 경우에 발생합니다.

간단한 예 :

  • 사용자 A는 동일한 쿼리를 두 번 실행합니다.
  • 그 사이에 사용자 B는 트랜잭션을 실행하고 커밋합니다.
  • 반복 불가능한 읽기 : 사용자 A가 조회 한 A 행은 두 번째로 다른 값을 갖습니다.
  • 팬텀 읽기 : 쿼리의 모든 행이 이전과 이후에 동일한 값을 갖지만 다른 행이 선택되고 있습니다 (B가 일부를 삭제하거나 삽입했기 때문에). 예 : select sum(x) from table;행이 추가되거나 삭제 된 경우 영향을받는 행 자체가 업데이트되지 않은 경우에도 다른 결과를 반환합니다.

위의 예에서 어떤 격리 수준을 사용해야합니까?

필요한 격리 수준은 응용 프로그램에 따라 다릅니다. “더 나은”격리 수준 (예 : 동시성 감소)에는 비용이 많이 듭니다.

예를 들어, 기본 키로 식별되는 단일 행에서만 선택하기 때문에 팬텀 읽기가 없습니다. 반복 불가능한 읽기를 수행 할 수 있으므로 문제가있는 경우이를 방지하는 격리 레벨을 원할 수 있습니다. Oracle에서 트랜잭션 A는 SELECT FOR UPDATE를 발행 할 수 있으며 트랜잭션 B는 A가 완료 될 때까지 행을 변경할 수 없습니다.


답변

내가 생각하는 간단한 방법은 다음과 같습니다.

반복 불가능 및 팬텀 읽기는 트랜잭션이 시작된 후 커밋 된 다음 다른 트랜잭션의 데이터 수정 작업과 관련이 있습니다.

반복 불가능한 읽기는 트랜잭션 이 다른 트랜잭션에서 커밋 된 UPDATES 를 읽는 경우 입니다. 동일한 행은 이제 거래가 시작되었을 때와 다른 값을 갖습니다.

비슷하지만 최선을 다하고에서 읽을 때 팬텀 읽기 인서트 및 / 또는 DELETES 다른 트랜잭션에서. 트랜잭션을 시작한 후 사라진 새 행이 있습니다.

더티 읽기는 반복 불가능 및 팬텀 읽기와 유사 하지만 커밋되지 않은 데이터 읽기와 관련이 있으며 다른 트랜잭션에서 UPDATE, INSERT 또는 DELETE를 읽을 때 발생하며 다른 트랜잭션이 아직 데이터를 커밋하지 않은 경우에 발생합니다. “진행 중”데이터를 읽는 중입니다.이 데이터는 완전하지 않을 수 있으며 실제로 커밋되지 않을 수 있습니다.


답변

이 기사 에서 설명한 것처럼 , 반복 불가능한 읽기 예외는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

  1. Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
  2. Bob의 게시물 레코드를 읽고 제목 열 값은 Transactions입니다.
  3. Alice는 지정된 게시물 레코드의 제목을 ACID 값으로 수정합니다.
  4. Alice는 데이터베이스 트랜잭션을 커밋합니다.
  5. Bob이 사후 레코드를 다시 읽으면이 테이블 행의 다른 버전을 보게됩니다.

에서 이 문서 에 대한 팬텀 읽기 , 당신은 다음과 같이 이상이 발생할 수 있음을 볼 수있다 :

여기에 이미지 설명을 입력하십시오

  1. Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
  2. Bob은 식별자 값이 1 인 게시 행과 관련된 모든 post_comment 레코드를 읽습니다.
  3. Alice는 식별자 값이 1 인 게시물 행과 관련된 새로운 post_comment 레코드를 추가합니다.
  4. Alice는 데이터베이스 트랜잭션을 커밋합니다.
  5. Bob이 post_id 열 값이 1 인 post_comment 레코드를 다시 읽으면이 결과 세트의 다른 버전을 관찰하게됩니다.

따라서 반복 불가능 읽기 는 단일 행에 적용되지만 팬텀 읽기 는 주어진 쿼리 필터링 기준을 만족하는 레코드 범위에 관한 것입니다.


답변

현상 읽기

  • 더티 읽기 : 다른 트랜잭션에서 UNCOMMITED 데이터 읽기
  • 반복 불가능한 읽기 :UPDATE다른 트랜잭션의쿼리에서COMMITTED 데이터 읽기
  • 팬텀 읽기 :다른 트랜잭션에서INSERT또는DELETE쿼리에서COMMITTED 데이터를 읽습니다 .

참고 : 다른 트랜잭션의 DELETE 문은 특정 경우 반복 불가능한 읽기를 일으킬 가능성이 매우 낮습니다. 불행히도 DELETE 문은 현재 트랜잭션이 쿼리하는 것과 동일한 행을 제거합니다. 그러나 이것은 드문 경우이며 각 테이블에 수백만 개의 행이있는 데이터베이스에서는 발생하지 않을 가능성이 훨씬 높습니다. 트랜잭션 데이터를 포함하는 테이블은 일반적으로 모든 프로덕션 환경에서 높은 데이터 볼륨을 갖습니다.

또한 실제 INSERT 또는 DELETES가 아닌 대부분의 사용 사례에서 UPDATES가 더 빈번한 작업 일 수 있습니다 (이 경우 반복 불가능한 읽기의 위험 만 남아 있습니다.이 경우 팬텀 읽기 는 불가능합니다). 이것이 바로 UPDATES가 INSERT-DELETE와 다르게 취급되고 그 결과로 나타나는 변칙의 이름도 다른 이유입니다.

UPDATES 만 처리하는 대신 INSERT-DELETE 처리와 관련된 추가 처리 비용도 있습니다.

다양한 격리 수준의 이점

  • READ_UNCOMMITTED는 아무것도 막지 않습니다. 제로 격리 수준입니다
  • READ_COMMITTED는 단 하나만 예방합니다. 즉 Dirty 읽기
  • REPEATABLE_READ는 더티 읽기와 반복 불가능 읽기의 두 가지 예외를 방지합니다.
  • 직렬화 가능은 더티 판독, 반복 불가능 판독 및 팬텀 판독의 세 가지 이상을 모두 방지합니다.

그렇다면 왜 트랜잭션 SERIALIZABLE을 항상 설정하지 않습니까? 위의 질문에 대한 대답은 SERIALIZABLE 설정으로 인해 트랜잭션이 매우 느려져 다시 원하지 않습니다.

실제로 트랜잭션 시간 소비는 다음 비율입니다.

SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED

따라서 READ_UNCOMMITTED 설정이 가장 빠릅니다 .

요약

실제로 사용 시간을 분석하고 격리 수준을 결정 하여 트랜잭션 시간을 최적화하고 대부분의 이상을 방지해야합니다.

기본적으로 데이터베이스에는 REPEATABLE_READ 설정이 있습니다.


답변

이 두 종류의 격리 수준간에 구현에 차이가 있습니다.
“반복 불가능한 읽기”의 경우 행 잠금이 필요합니다.
“팬텀 읽기”의 경우, 테이블 잠금조차도 범위 잠금이 필요합니다. 2 단계 잠금 프로토콜
을 사용하여이 두 가지 수준을 구현할 수 있습니다 .


답변

반복 불가능한 읽기가있는 시스템에서 트랜잭션 A의 두 번째 쿼리 결과는 트랜잭션 B의 업데이트를 반영합니다. 새로운 금액이 표시됩니다.

팬텀 읽기를 허용하는 시스템에서 트랜잭션 B가 ID = 1 인 새 행 을 삽입 하면 두 번째 쿼리가 실행될 때 트랜잭션 A가 새 행을 보게됩니다. 즉, 팬텀 읽기는 반복 불가능한 읽기의 특별한 경우입니다.


답변

받아 들여진 대답은 무엇보다도 둘 사이의 소위 구별이 실제로 중요하지 않다는 것을 나타냅니다.

“행이 두 번 검색되고 행 내의 값이 읽기간에 서로 다른 경우”는 동일한 행이 아니며 (올바른 RDB에서 동일한 튜플이 아님) “정확한 경우 두 번째 쿼리에서 반환 된 행은 첫 번째 쿼리와 다릅니다. “

“어떤 격리 수준을 사용해야합니까?”라는 질문에 대해, 데이터가 누군가 어딘가에 매우 중요할수록 Serializable이 유일한 합리적인 옵션 일 것입니다.