2017년 6월 5일 날씨 - 비.
이틀 전 이전 공부노트를 정리하다가 더티 읽기(Dirty Read), 팬텀 읽기(Phantom Read), 비반복 읽기(Non-Repeatable Read), 손실된 업데이트(Loss Update)의 개념이 트랜잭션 동시성으로 인해 발생하는 문제에 대해 다소 모호한 것을 발견하여 검토해 보았습니다. 다시 한 번 내 자신의 내용을 넣어 모든 사람의 학습을 용이하게 하기 위해 이해를 다음과 같이 요약하고 정리했습니다.
잠금은 다른 트랜잭션이 지정된 리소스에 액세스하는 것을 방지하는 수단입니다. 잠금은 동시성 제어를 달성하는 주요 방법이며 여러 사용자가 데이터 불일치 없이 동시에 동일한 데이터베이스의 데이터를 조작할 수 있도록 하는 중요한 보장입니다. 일반적으로 잠금은 더티 읽기, 반복 불가능한 읽기 및 팬텀 읽기를 방지합니다.
1.Dirty Read——트랜잭션은 다른 트랜잭션이 커밋하지 않은 데이터를 읽습니다.
자세한 설명: 트랜잭션이 데이터에 액세스하여 데이터를 수정하고 있지만 수정 사항이 아직 데이터베이스에 제출되지 않은 경우 다른 트랜잭션도 해당 데이터에 액세스한 후 해당 데이터를 사용합니다. 이 데이터는 아직 커밋되지 않았기 때문에 다른 트랜잭션에서 읽은 데이터는 더티 데이터이며 더티 데이터를 기반으로 한 작업이 올바르지 않을 수 있습니다.
트랜잭션 T1: 데이터 업데이트
트랜잭션 T1: 더티 데이터(dirty data)라고 불리는 이 프로세스를 더티 읽기(dirty reading)라고 합니다.
더티 읽기는 한 트랜잭션 A가 다른 트랜잭션 B에 의해 수정되었지만 아직 커밋되지 않은 데이터를 읽을 때 발생합니다. B가 롤백하면 트랜잭션 A가 잘못된 데이터를 읽습니다. 이는 반복 불가능 읽기와 유사하지만 두 번째 트랜잭션은 커밋할 필요가 없습니다.
더티 읽기 문제 해결: 수정 시 배타적 잠금을 추가하고 트랜잭션이 커밋될 때까지 해제합니다. 읽을 때 공유 잠금을 추가하고, 데이터를 읽을 때 공유 잠금을 추가합니다. 데이터 읽기 프로세스 중에 다른 트랜잭션은 데이터를 수정하지 않습니다.) 데이터에 대한 트랜잭션 작업은 허용되지 않으며 읽기만 허용됩니다. 나중에 업데이트 작업이 있으면 배타적 잠금으로 변환되며 다른 트랜잭션은 데이터를 읽을 수 없습니다. 읽기 및 쓰기에 참여할 권리가 있으므로 더티 읽기 문제를 방지할 수 있습니다. 그러나 트랜잭션 1이 데이터를 읽는 동안 다른 트랜잭션도 데이터를 읽었을 가능성이 있으며, 읽기가 완료된 후 공유 잠금이 해제됩니다. 트랜잭션이 제출됩니다. 다른 트랜잭션이 데이터를 다시 읽을 때 데이터가 일치하지 않으면 반복 불가능한 읽기 문제가 발생하므로 반복 불가능한 읽기 문제를 피할 수 없습니다.
2.
Phantom)——동일한 트랜잭션에서 동일한 작업을 두 번 읽는 데 사용되며, 얻는 레코드 수가 다릅니다. 자세한 설명: 팬텀 읽기는 트랜잭션이 독립적으로 실행되지 않을 때 발생하는 현상을 말합니다. 예를 들어 첫 번째 트랜잭션은 테이블의 데이터를 수정하는데, 이 수정에는 테이블의 모든 데이터 행이 포함됩니다. 동시에 두 번째 트랜잭션도 이 테이블의 데이터를 수정합니다. 이 수정으로 인해 테이블에 새 데이터 행이 삽입됩니다. 그러면 나중에 첫 번째 트랜잭션을 수행한 사용자는 마치 환각이 발생한 것처럼 테이블에 아직 수정되지 않은 데이터 행이 있다는 것을 알게 될 것입니다.
트랜잭션 T1: 테이블의 모든 레코드 쿼리
두 번째 쿼리에서 얻은 기록이 다릅니다. 이를 팬텀 판독이라고 합니다.
참고: 팬텀 리딩의 초점은 추가 또는 삭제입니다.
환상 읽기는 두 개의 동일한 쿼리가 실행될 때 발생하며, 두 번째 쿼리에서 반환된 결과 집합은 첫 번째 쿼리와 다릅니다.
상황: 범위 잠금이 없습니다.
피하는 방법: 직렬화된 격리 모드 구현은 모든 하위 수준 격리에서 발생할 수 있습니다.
팬텀 읽기 문제 해결: 범위 잠금 RangeS RangeS_S 모드는 검색 범위를 읽기 전용으로 잠그는 데 사용되므로 팬텀 읽기 문제를 방지합니다. 3.
Nonrepeatable Read——동일한 트랜잭션에서 동일한 데이터를 두 번 읽어 내용이 다릅니다.
거래 T1: 기록 쿼리
~ 트랜잭션 T1: 레코드 쿼리 중 ‑‑‑‑‑‑-‑‑‑‑‑‑‑‑—‑‑‑‑‑‑‑‑─────> 동일한 데이터가 두 번 쿼리되지만, 사용 가능한 콘텐츠가 다르며 이를 반복 불가능 읽기라고 합니다.참고: 반복되지 않는 읽기는 수정에 중점을 둡니다.
잠금 기반 병렬 제어 방식에서는 select 실행 시 읽기 잠금을 추가하지 않으면 반복 불가능한 읽기 문제가 발생합니다.
다중 버전 병렬 제어 메커니즘에서는 커밋 충돌이 발생한 트랜잭션을 롤백해야 하지만 해제할 때 반복 불가능한 읽기 문제가 발생합니다.
이 문제가 발생하지 않도록 방지하는 두 가지 전략이 있습니다.
(1) 트랜잭션 1이 커밋되거나 롤백될 때까지 트랜잭션 2의 실행을 지연합니다. 이 전략은 잠금을 사용할 때 적용됩니다.
(2) 다중 버전 병렬 제어에서는 트랜잭션 2가 먼저 제출될 수 있고 트랜잭션 1은 이전 버전의 데이터에서 계속 실행됩니다. 마지막으로 트랜잭션 1이 커밋을 시도하면 데이터베이스는 그 결과가 트랜잭션 1과 트랜잭션 2를 순차적으로 실행했을 때와 동일한지 확인합니다. 그렇다면 트랜잭션 1이 성공적으로 제출되고, 그렇지 않으면 트랜잭션 1이 롤백됩니다.
반복 불가능한 읽기 문제 해결: 데이터를 읽을 때 공유 잠금을 추가하고, 데이터를 쓸 때 배타적 잠금을 추가하고, 트랜잭션 제출 후에만 잠금을 해제하세요. 읽을 때 데이터를 수정할 수 있는 다른 방법은 없습니다. 트랜잭션 중에 데이터를 몇 번이나 읽어도 데이터는 일관되므로 반복할 수 없는 읽기 문제가 발생하지 않습니다.
4.Lost Update(Lost Update)
트랜잭션 T1은 데이터를 읽고 일부 작업을 수행한 후 데이터를 업데이트합니다. 트랜잭션 T2도 동일한 작업을 수행하므로 T1과 T2가 데이터를 업데이트하면 서로의 업데이트를 덮어쓰게 되어 오류가 발생할 수 있습니다.
5. 위의 격리 수준 문제를 처리하려면 다음 방법을 사용하십시오.
5가지 트랜잭션 격리 수준:
(1) TRANSACTION_NONE은 트랜잭션을 사용하지 않습니다.
(2) TRANSACTION_READ_UNCOMMITTED는 더티 읽기를 허용합니다.
(3) TRANSACTION_READ_COMMITTED는 가장 일반적으로 사용되는 격리 수준인 더티 읽기(dirty read)를 방지하며 대부분의 데이터베이스에 대한 기본 격리 수준입니다.
(4) TRANSACTION_REPEATABLE_READ는 더티 읽기 및 반복 불가능한 읽기를 방지할 수 있습니다.
(5) TRANSACTION_SERIALIZABLE은 더티 읽기(dirty read), 반복 불가능한 읽기 및 팬텀 읽기(트랜잭션 직렬화)를 방지하여 데이터베이스 효율성을 저하시킵니다.
위의 5가지 트랜잭션 격리 수준은 연결 인터페이스에 정의된 정적 상수입니다. setTransactionIsolation(int level) 메서드를 사용하여 트랜잭션 격리 수준을 설정하세요.
예: con.setTransactionIsolation(Connection.REPEATABLE_READ).
참고: 트랜잭션의 격리 수준은 데이터베이스에 의해 제한됩니다. 서로 다른 데이터베이스에서 지원하는 격리 수준이 반드시 동일할 필요는 없습니다.
위 내용은 더티 읽기, 팬텀 읽기, 반복 불가능한 읽기 및 업데이트 인스턴스 손실의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!