반복 불가능한 읽기와 팬텀 읽기의 차이점은 무엇입니까?
반복 불가능한 읽기와 팬텀 읽기의 차이점은 무엇입니까?
Wikipedia 의 Isolation (데이터베이스 시스템) 기사를 읽었 지만 몇 가지 의심이 있습니다. 아래 예제에서 반복 불가능한 읽기 및 팬텀 읽기 ?
거래 ASELECT 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 를 읽는 경우 입니다. 동일한 행은 이제 거래가 시작되었을 때와 다른 값을 갖습니다.
팬텀 읽기는 비슷하지만 커밋 된 INSERTS 및 / 또는 다른 트랜잭션에서 DELETES 를 읽을 때 유사 합니다. 트랜잭션을 시작한 후 사라진 새 행이 있습니다.
더티 읽기는 반복 불가능 및 팬텀 읽기와 유사 하지만 커밋되지 않은 데이터 읽기와 관련이 있으며 다른 트랜잭션에서 UPDATE, INSERT 또는 DELETE를 읽을 때 발생하며 다른 트랜잭션이 아직 데이터를 커밋하지 않은 경우에 발생합니다. "진행 중"데이터를 읽는 중입니다.이 데이터는 완전하지 않을 수 있으며 실제로 커밋되지 않을 수 있습니다.
에서 설명하고있는 바와 같이 이 문서 는 비 반복 읽기 이상으로 다음과 같습니다 :
- Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
- Bob의 게시물 레코드를 읽고 제목 열 값은 Transactions입니다.
- Alice는 지정된 게시물 레코드의 제목을 ACID 값으로 수정합니다.
- Alice는 데이터베이스 트랜잭션을 커밋합니다.
- Bob이 포스트 레코드를 다시 읽으면이 테이블 행의 다른 버전을 보게됩니다.
에서 이 문서 에 대한 팬텀 읽기 , 당신은 다음과 같이 이상이 발생할 수 있음을 볼 수있다 :
- Alice와 Bob은 두 개의 데이터베이스 트랜잭션을 시작합니다.
- Bob은 식별자 값이 1 인 게시 행과 관련된 모든 post_comment 레코드를 읽습니다.
- Alice는 식별자 값이 1 인 게시물 행과 관련된 새로운 post_comment 레코드를 추가합니다.
- Alice는 데이터베이스 트랜잭션을 커밋합니다.
- If Bob’s re-reads the post_comment records having the post_id column value equal to 1, he will observe a different version of this result set.
So, while the Non-Repeatable Read applies to a single row, the Phantom Read is about a range of records which satisfy a given query filtering criteria.
Read phenomena
- Dirty reads: read UNCOMMITED data from another transaction
- Non-repeatable reads: read COMMITTED data from an
UPDATE
query from another transaction - Phantom reads: read COMMITTED data from an
INSERT
orDELETE
query from another transaction
Note : DELETE statements from another transaction, also have a very low probability of causing Non-repeatable reads in certain cases. It happens when the DELETE statement unfortunately, removes the very same row which your current transaction was querying. But this is a rare case, and far more unlikely to occur in a database which have millions of rows in each table. Tables containing transaction data usually have high data volume in any production environment.
Also we may observe that UPDATES may be a more frequent job in most use cases rather than actual INSERT or DELETES (in such cases, danger of non-repeatable reads remain only - phantom reads are not possible in those cases). This is why UPDATES are treated differently from INSERT-DELETE and the resulting anomaly is also named differently.
There is also an additional processing cost associated with handling for INSERT-DELETEs, rather than just handling the UPDATES.
Benefits of different isolation levels
- READ_UNCOMMITTED prevents nothing. It's the zero isolation level
- READ_COMMITTED prevents just one, i.e. Dirty reads
- REPEATABLE_READ prevents two anomalies: Dirty reads and Non-repeatable reads
- SERIALIZABLE prevents all three anomalies: Dirty reads, Non-repeatable reads and Phantom reads
Then why not just set the transaction SERIALIZABLE at all times? Well, the answer to the above question is: SERIALIZABLE setting makes transactions very slow, which we again don't want.
In fact transaction time consumption is in the following rate:
SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED
So READ_UNCOMMITTED setting is the fastest.
Summary
Actually we need to analyze the use case and decide an isolation level so that we optimize the transaction time and also prevent most anomalies.
Note that databases by default have REPEATABLE_READ setting.
There is a difference in the implementation between these two kinds isolation levels.
For "non-repeatable read", row-locking is needed.
For "phantom read",scoped-locking is needed, even a table-locking.
We can implement these two levels by using two-phase-locking protocol.
In a system with non-repeatable reads, the result of Transaction A's second query will reflect the update in Transaction B - it will see the new amount.
In a system that allows phantom reads, if Transaction B were to insert a new row with ID = 1, Transaction A will see the new row when the second query is executed; i.e. phantom reads are a special case of non-repeatable read.
The accepted answer indicates most of all that the so-called distinction between the two is actually not significant at all.
If "a row is retrieved twice and the values within the row differ between reads", then they are not the same row (not the same tuple in correct RDB speak) and it is then indeed by definition also the case that "the collection of rows returned by the second query is different from the first".
As to the question "which isolation level should be used", the more your data is of vital importance to someone, somewhere, the more it will be the case that Serializable is your only reasonable option.
I think there are some difference between Non-repeateable-read & phantom-read.
The Non-repeateable means there are tow transaction A & B. if B can notice the modification of A, so maybe happen dirty-read, so we let B notices the modification of A after A committing.
There is new issue: we let B notice the modification of A after A committing, it means A modify a value of row which the B is holding, sometime B will read the row again, so B will get new value different with first time we get, we call it Non-repeateable, to deal with the issue, we let the B remember something(cause i don't know what will be remembered yet) when B start.
새로운 해결책에 대해 생각해 봅시다. 새로운 문제가 있음을 알 수 있습니다. B가 무언가를 기억하게 만들었으므로 A에서 발생한 모든 일에 영향을받을 수는 없지만 B가 일부 데이터를 테이블과 B에 삽입하려는 경우 테이블을 점검하여 레코드가 없는지 확인하십시오. 그러나이 데이터는 A에 의해 삽입되었으므로 약간의 오류가 발생할 수 있습니다. 우리는 그것을 Phantom-read라고 부릅니다.
반복 불가능한 읽기는 격리 수준이며 팬텀 읽기 (다른 트랜잭션에 의해 커밋 된 값 읽기)는 개념 (읽기 유형 (예 : 더티 읽기 또는 스냅 샷 읽기))입니다. 반복 불가능한 읽기 격리 수준은 팬텀 읽기를 허용하지만 더티 읽기 또는 스냅 샷 읽기는 허용하지 않습니다.
'IT' 카테고리의 다른 글
R의 플롯에서 글꼴 크기를 늘리는 방법은 무엇입니까? (0) | 2020.07.01 |
---|---|
사전을 해싱? (0) | 2020.07.01 |
BestPractice-문자열의 첫 문자를 소문자로 변환 (0) | 2020.07.01 |
매일 자정에 스크립트를 실행할 크론을 작성하는 방법은 무엇입니까? (0) | 2020.07.01 |
Python 실행 파일이 libpython 공유 라이브러리를 찾을 수 없음 (0) | 2020.07.01 |