Non-Repeatable Read와 Phantom Read의 차이점은 무엇입니까?
반복 불가능한 판독과 팬텀 판독의 차이점은 무엇입니까?
Wikipedia에서 Isolation(데이터베이스 시스템) 기사를 읽었는데 몇 가지 의문점이 있습니다.아래 예에서는 어떤 일이 발생합니까? 반복 불가능한 읽기 및 팬텀 읽기입니다.
### 트랜잭션 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가 완료될 때까지 행을 변경할 수 없습니다.
간단하게 생각할 수 있는 방법은 다음과 같습니다.
반복 불가능한 읽기 및 팬텀 읽기 모두 트랜잭션 시작 후 커밋된 다른 트랜잭션의 데이터 수정 작업과 관련이 있습니다.
반복 불가능한 읽기는 트랜잭션이 다른 트랜잭션에서 커밋된 업데이트를 읽는 경우입니다.이제 같은 행의 값이 트랜잭션이 시작되었을 때와 다릅니다.
팬텀 판독은 유사하지만 다른 트랜잭션에서 커밋된 INSERT 및/또는 DELETERS를 읽을 때 유사합니다.트랜잭션을 시작한 후 사라진 새 행이 있습니다.
더티 판독은 반복 불가능한 판독 및 팬텀 판독과 유사하지만 UNCOMMITITED 데이터 판독과 관련이 있으며 다른 트랜잭션에서 UPDATE, INSERT 또는 DELETE가 읽히고 다른 트랜잭션이 아직 데이터를 커밋하지 않은 경우에 발생합니다.이는 "진행 중" 데이터를 읽고 있으며, 이는 완전하지 않을 수 있으며 실제로 커밋되지 않을 수 있습니다.
Non-Repeatable Read 이상은 다음과 같습니다.
- Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
- Bob's는 투고 기록을 읽으며 타이틀 컬럼 값은 Transactions입니다.
- Alice는 지정된 포스트 레코드의 제목을 ACID 값으로 변경합니다.
- Alice는 데이터베이스 트랜잭션을 커밋합니다.
- Bob이 투고 레코드를 다시 읽으면 이 테이블 행의 다른 버전이 표시됩니다.
팬텀 판독 이상은 다음과 같이 발생할 수 있습니다.
- Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
- Bob's는 식별자 값이 1인 포스트 행과 관련된 모든 포스트_comment 레코드를 읽습니다.
- Alice는 식별자 값이 1인 포스트 행과 관련된 새로운 포스트 코멘트레코드를 추가합니다.
- Alice는 데이터베이스 트랜잭션을 커밋합니다.
- Bob이 post_id 컬럼 값이 1인 post_comment 레코드를 다시 읽을 경우 이 결과 세트의 다른 버전을 확인합니다.
따라서 Non-Repeatable Read는 단일 행에 적용되는 반면 Phantom Read는 지정된 쿼리 필터링 기준을 충족하는 레코드 범위에 관한 것입니다.
현상을 읽다
- 더티 읽기: 다른 트랜잭션에서 UNCOMMITED 데이터를 읽습니다.
- 반복할 수 없는 읽기: COMMITED 데이터 읽기
UPDATE
- 팬텀 읽기: COMMITED 데이터 읽기
INSERT
★★★★★★★★★★★★★★★★★」DELETE
주의: 다른 트랜잭션의 DELETE 스테이트먼트는 특정 상황에서 반복 불가능한 읽기를 일으킬 가능성이 매우 낮습니다.이 문제는 DELETE 스테이트먼트가 현재 트랜잭션에서 쿼리하고 있는 행과 동일한 행을 삭제할 때 발생합니다.그러나 이는 드문 경우이며 각 테이블에 수백만 개의 행이 있는 데이터베이스에서는 발생할 가능성이 훨씬 낮습니다.트랜잭션 데이터를 포함하는 테이블은 일반적으로 모든 프로덕션 환경에서 데이터 볼륨이 높습니다.
또한 대부분의 사용 사례에서 UPDATES가 실제 INSERT 또는 DELETES보다 더 빈번한 작업일 수 있습니다(이 경우 반복 불가능한 판독의 위험만 남습니다. 이러한 경우에는 팬텀 판독이 불가능합니다).그렇기 때문에 UPDATES는 INSERT-DELETE와 다르게 취급되며 그 결과 발생하는 이상도 다르게 명명됩니다.
업데이트 처리뿐만 아니라 INSERT-DELETE 처리에 따른 추가 처리 비용도 있습니다.
다양한 격리 수준의 이점
- READ_UNCOMMITED는 아무것도 방지하지 않습니다.격리 수준이 0인 경우입니다.
- READ_COMMITED는 1개(불량 읽기 등)만 방지합니다.
- REEPTABLE_READ는 다음 두 가지 이상을 방지합니다.지저분한 읽기 및 반복 불가능한 읽기
- 시리얼화 가능: 3가지 이상 징후를 모두 방지합니다.지저분한 읽기, 반복 불가능한 읽기 및 팬텀 읽기
그럼 왜 항상 트랜잭션을 직렬화할 수 있도록 설정하지 않는 거죠?위의 질문에 대한 답변은 다음과 같습니다.SERIALFIGLE 설정은 트랜잭션을 매우 느리게 만들지만, 우리는 다시 한 번 원하지 않습니다.
실제로 트랜잭션 시간 소비량은 다음과 같습니다.
시리얼화 가능> 반복 가능_읽기> 읽기_COMMITED > READ_커밋되어 있지 않다
읽어주세요.UNCOMMITED 설정이 가장 빠릅니다.
요약
실제로 트랜잭션 시간을 최적화하고 대부분의 이상 징후를 방지하기 위해 사용 사례를 분석하고 격리 수준을 결정해야 합니다.
기본 데이터베이스에는 REPETABLE_READ 설정이 있을 수 있습니다.관리자 및 설계자는 플랫폼의 성능을 향상시키기 위해 이 설정을 기본값으로 선택하는 데 선호할 수 있습니다.
이들 2종류의 격리 수준 사이에는 구현에 차이가 있습니다.
"반복 불가 읽기"의 경우 행 잠금이 필요합니다.
「팬텀 판독」의 경우는, 테이블 잠금도 포함해 스코프 잠금 기능이 필요합니다.
2상 잠금 프로토콜을 사용하여 이 두 가지 수준을 구현할 수 있습니다.
반복 불가능한 읽기가 있는 시스템에서는 트랜잭션 A의 두 번째 쿼리 결과가 트랜잭션 B의 업데이트를 반영하고 새로운 금액이 표시됩니다.
팬텀 읽기를 허용하는 시스템에서 트랜잭션 B가 ID = 1인 새 행을 삽입하면 트랜잭션 A에 두 번째 쿼리가 실행될 때 새 행이 표시됩니다. 즉, 팬텀 읽기가 허용되지 않는 특수한 경우입니다.
비반복 읽기(퍼지 읽기)는 트랜잭션에서 같은 행을 적어도 두 번 읽지만 다른 트랜잭션에서 동일한 행의 데이터를 업데이트하고 동시에 커밋하기 때문에 첫 번째와 두 번째 읽기 사이에 같은 행의 데이터가 다른 것을 말합니다.
팬텀 리드는 트랜잭션에서 같은 테이블을 적어도 두 번 읽지만 다른 트랜잭션에서 행을 삽입 또는 삭제하고 동시에 커밋하기 때문에 첫 번째와 두 번째 리드 사이에 같은 테이블의 행 수가 다르다는 것입니다.
MySQL과 2개의 명령 프롬프트를 사용하여 반복 불가능한 읽기 및 팬텀 읽기를 실험했습니다.
비반복 판독 및 팬텀 판독 실험의 경우 비반복 판독 및 팬텀 판독이 발생하도록 격리 레벨을 설정합니다.
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
그리고 아래와 같이 와 를 사용하여 테이블을 만들었습니다.
person
삭제:
아이디 | 이름. |
---|---|
1 | 존. |
2 | 데이빗 |
먼저 반복 불가능한 읽기의 경우 MySQL 쿼리를 사용하여 다음 단계를 수행했습니다.
흐름 | 트랜잭션 1(T1) | 트랜잭션 2(T2) | 설명. |
---|---|---|---|
순서 1 | BEGIN; |
T1이 시작됩니다. | |
순서 2 | BEGIN; |
T2가 시작됩니다. | |
순서 3 | SELECT * FROM person WHERE id = 2; 2 데이비드 |
은 T1로 읽힌다.David . |
|
순서 4 | UPDATE person SET name = 'Tom' WHERE id = 2; |
T2를 갱신하다David 로로 합니다.Tom . |
|
순서 5 | COMMIT; |
T2 커밋 | |
순서 6 | SELECT * FROM person WHERE id = 2; 2 톰 |
은 T1로 읽힌다.Tom David T2 밋 t t 。*반복 불가 판독 발생!! |
|
순서 7 | COMMIT; |
T1은 커밋합니다. |
두 번째 팬텀 읽기에서는 MySQL 쿼리로 다음 단계를 수행했습니다.
흐름 | 트랜잭션 1(T1) | 트랜잭션 2(T2) | 설명. |
---|---|---|---|
순서 1 | BEGIN; |
T1이 시작됩니다. | |
순서 2 | BEGIN; |
T2가 시작됩니다. | |
순서 3 | SELECT * FROM person; 1 존 2 데이비드 |
T1은 2 행을 읽습니다. | |
순서 4 | INSERT INTO person VALUES (3, 'Tom'); |
로 행을 합니다.3 ★★★★★★★★★★★★★★★★★」Tom 로로 합니다.person table.syslog를 클릭합니다. |
|
순서 5 | COMMIT; |
T2 커밋 | |
순서 6 | SELECT * FROM person; 1 존 2 데이비드 3 톰 |
T1은 T2 커밋 후 2 행이 아닌 3 행을 읽습니다.*팬텀 판독이 발생!! |
|
순서 7 | COMMIT; |
T1은 커밋합니다. |
받아들여진 답변은 그 둘 사이의 소위 말하는 구분이 실제로는 전혀 중요하지 않다는 것을 나타낸다.
행이 두 번 검색되고 행 내의 값이 읽기 간에 다를 경우 행은 동일하지 않으며(올바른 RDB 스피크에서는 동일하지 않음), 정의상 "두 번째 쿼리에 의해 반환되는 행의 집합이 첫 번째 쿼리와 다르다"는 의미도 있습니다.
"어느 격리 수준을 사용해야 하는가?"라는 질문에 대해서는 데이터가 누군가에게 매우 중요할수록 Serializable이 유일한 합리적인 옵션인 경우가 많아집니다.
Non-repeatable read와 phantom read에는 몇 가지 차이가 있다고 생각합니다.
Non-repeatable은 견인 거래 A와 B가 있는 것을 의미하며, B가 A의 수정을 눈치챌 수 있다면, A가 커밋한 후에 B에게 A의 수정을 알립니다.
새로운 문제가 있습니다.A가 커밋한 후에 B에게 A의 변경을 통지합니다.A는 B가 보유하고 있는 행의 값을 수정하고, 언젠가 B가 행을 다시 읽게 되므로 B는 처음 받았을 때와는 다른 새로운 값을 얻을 수 있으므로 Non-repeatable이라고 합니다.이 문제에 대처하기 위해 B에게 무언가를 기억시킵니다(기억할 수 없기 때문에).B가 시작할 때 아직)를 누릅니다.
새로운 솔루션을 생각해 봅시다.B에게도 새로운 문제가 있음을 알 수 있기 때문에 A에서 일어난 일은 B에 영향을 주지 않습니다만, B가 테이블에 데이터를 삽입하고 싶은 경우, B가 레코드가 없는 것을 확인하고 싶은 경우, 이 데이터는 A에 의해 삽입되어 있기 때문에 오류가 발생할 수 있습니다.우리는 그것을 팬텀-리드라고 부른다.
Non-trapable read는 격리 수준이고 팬텀 read(다른 트랜잭션에 의한 커밋 값 읽기)는 개념(예: 더티 read 또는 스냅샷 read)입니다.반복할 수 없는 읽기 격리 레벨로 팬텀 읽기는 가능하지만 지저분한 읽기나 스냅샷 읽기는 할 수 없습니다.
반복 불가능한 읽기 및 팬텀 읽기 모두 T1이 완료되기 전에 커밋된 다른 트랜잭션 T2로부터의 변화를 보는 트랜잭션 T1에서 발생합니다.차이점은 반복 불가능한 읽기는 동일한 논리 행에 대해 다른 값을 반환한다는 것입니다(예를 들어 기본 키가 employee_id인 경우 두 결과에서 특정 직원의 급여가 다를 수 있습니다).팬텀 판독에서는 두 개의 다른 행 세트가 반환되지만 두 세트에 나타나는 모든 행에 대해 열 값은 동일합니다.
언급URL : https://stackoverflow.com/questions/11043712/what-is-the-difference-between-non-repeatable-read-and-phantom-read
'programing' 카테고리의 다른 글
WooCommerce에서 체크아웃 시 기본 배송 및 결제 옵션을 비활성화하려면 어떻게 해야 합니까? (0) | 2023.02.28 |
---|---|
반응 네이티브 버튼의 배경색을 변경하는 방법 (0) | 2023.02.28 |
Ajax를 통해 제출할 때 양식 태그를 사용하는 이유는 무엇입니까? (0) | 2023.02.23 |
WordPress, jQuery UI CSS 파일? (0) | 2023.02.23 |
MongoDB: 문서의 ID를 "공개"로 사용해도 안전한가? (0) | 2023.02.23 |