SQL Server에서 "read committed"와 "repeatable read"의 차이
나는 위의 고립 수준이 매우 비슷하다고 생각한다.가장 큰 차이가 무엇인지 좋은 예를 들어 설명해주실 수 있나요?
Read committed는 현재 읽기가 커밋된 모든 데이터의 읽기를 보장하는 격리 수준입니다.그것은 단순히 독자들이 중간적이고, 약속되지 않은, 더러운 어떤 읽기도 보지 못하도록 제한한다.트랜잭션이 읽기를 다시 발행하여 동일한 데이터를 찾을 경우 데이터를 읽은 후에는 데이터를 자유롭게 변경할 수 있다는 약속은 전혀 약속하지 않습니다.
반복 가능 읽기는 읽기 커밋 수준의 보증과 더불어 데이터 읽기가 변경될 수 없음을 보장하는 상위 격리 수준입니다. 트랜잭션에서 동일한 데이터를 다시 읽으면 이전에 읽은 데이터가 그대로 유지되고, 변경되지 않으며, 읽을 수 있는 데이터를 찾습니다.
다음 분리 레벨은 시리얼화 가능하기 때문에 보다 강력한 보증을 제공합니다.반복 가능한 모든 읽기 보증과 더불어 후속 읽기에서도 새로운 데이터를 볼 수 없습니다.
열 C가 있는 테이블 T에 행이 하나 있다고 가정하고 값이 '1'이라고 가정합니다.그리고 다음과 같은 간단한 작업이 있다고 가정합니다.
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
이는 테이블 T에서2개의 판독치를 발행하고 그 사이에1분간의 지연을 갖는 간단한 작업입니다.
- READ COMMITED에서 두 번째 SELECT는 모든 데이터를 반환할 수 있습니다.동시 트랜잭션은 레코드를 업데이트하거나 삭제하거나 새 레코드를 삽입할 수 있습니다.두 번째 선택 항목에서는 항상 새 데이터가 표시됩니다.
- Repeatable READ에서 두 번째 SELECT는 첫 번째 SELECT에서 반환된 행을 변경하지 않고 표시하도록 보장합니다.1분 내에 동시 트랜잭션에 의해 새 행을 추가할 수 있지만 기존 행을 삭제하거나 변경할 수 없습니다.
- UNDERIABLE(직렬 가능) 읽기에서 두 번째 선택 항목은 첫 번째 선택 항목과 동일한 행을 볼 수 있습니다.행을 변경하거나 삭제할 수 없으며 동시 트랜잭션에 의해 새 행을 삽입할 수 없습니다.
위의 논리를 따르면 Serializable 트랜잭션은 쉽게 사용할 수 있지만 행을 수정, 삭제 또는 삽입할 수 없는 모든 동시 작업을 항상 완전히 차단한다는 것을 금방 알 수 있습니다.의 기본 트랜잭션 분리 수준입니다.그물System.Transactions
수 , 그 결과 발생하는 을 설명해 .이것은 통상, 그 결과 발생하는 최악의 퍼포먼스를 설명해 줍니다.
마지막으로 스냅샷 분리 수준도 있습니다.스냅샷 분리 레벨은 시리얼 가능과 동일한 보증을 제공하지만 동시 트랜잭션이 데이터를 수정할 수 없도록 하는 것은 아닙니다.대신, 모든 독자가 자신의 세계 버전을 보도록 강요한다(스냅샷).따라서 동시 업데이트를 차단하지 않기 때문에 프로그래밍이 매우 쉽고 확장성도 뛰어납니다.단, 이러한 이점에는 추가 서버 리소스 사용이라는 비용이 수반됩니다.
추가 읽기:
반복 가능한 읽기
데이터베이스 상태는 트랜잭션 시작 시부터 유지됩니다.session1에서 값을 취득한 후 session2에서 값을 갱신하면 session1에서 값을 다시 취득하면 같은 결과가 반환됩니다.판독은 반복 가능합니다.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
읽기 커밋
트랜잭션의 컨텍스트 내에서 항상 가장 최근에 커밋된 값을 가져옵니다.session1에서 값을 취득하고 session2에서 값을 갱신한 후 session1에서 값을 다시 취득하면 session2에서 변경된 값을 얻을 수 있습니다.마지막으로 커밋된 행을 읽습니다.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Bob
말이 되나요?
단순히 이 스레드에 대한 나의 읽기와 이해에 따른 답변과 @remus-rusanu의 답변은 다음과 같은 간단한 시나리오에 기초하고 있습니다.
거래에는 A와 B가 있습니다.이러한 조작은, 다음의 순서로 실행됩니다.
- 트랜잭션 B는 먼저 표 X에서 읽습니다.
- 트랜잭션 A가 테이블 X에 씁니다.
- 그런 다음 트랜잭션 B는 표 X에서 다시 판독합니다.
- 읽기 커밋되지 않음:트랜잭션 B는 트랜잭션 A에서 커밋되지 않은 데이터를 읽을 수 있으며 A의 쓰기에 따라 다른 행을 볼 수 있습니다.잠금이 전혀 없다
- 읽기 커밋:트랜잭션 B는 트랜잭션 A로부터 커밋된 데이터만 읽을 수 있으며 COMMITED A의 쓰기에 따라 다른 행을 볼 수 있습니다.단순 잠금이라고 부를 수 있을까요?
- 반복 가능 읽기:트랜잭션 B는 트랜잭션 A가 수행하는 것과 동일한 데이터(행)를 읽습니다.그러나 트랜잭션 A는 다른 행을 변경할 수 있습니다.행 수준 블록
- 시리얼 가능:트랜잭션 B는 이전과 동일한 행을 읽고 트랜잭션 A는 테이블에서 읽거나 쓸 수 없습니다.테이블 레벨 블록
- 스냅샷: 모든 트랜잭션에는 자체 복사본이 있으며, 현재 작업 중입니다.저마다 생각이 다르다
이미 답변이 받아들여진 오래된 질문이지만 SQL Server의 잠금 동작을 어떻게 변화시키는지에 대해 이 두 가지 분리 수준을 생각해 보고 싶습니다.이것은 저처럼 교착 상태를 디버깅하는 사람들에게 도움이 될 수 있습니다.
READ COMMITED(기본값)
공유 잠금은 SELECT에서 실행되며 SELECT 문이 완료되면 해제됩니다.이를 통해 시스템은 커밋되지 않은 데이터의 더러운 읽기가 발생하지 않도록 보장할 수 있습니다.다른 트랜잭션에서는 SELECT 완료 후 트랜잭션 완료 전에 기본 행을 변경할 수 있습니다.
반복 가능한 읽기
공유 잠금은 SELECT에서 실행되며 트랜잭션이 완료된 후에만 해제됩니다.이렇게 하면 트랜잭션 중에 읽은 값이 변경되지 않습니다(트랜잭션이 완료될 때까지 잠긴 상태로 유지되기 때문입니다).
이 의심을 간단한 도표로 설명하려고 한다.
읽기 커밋:이 분리 수준에서 트랜잭션 T1은 트랜잭션 T2에 의해 커밋된 X의 업데이트된 값을 읽습니다.
반복 가능한 읽기:이 분리 수준에서 거래 T1은 거래 T2에 의해 커밋된 변경을 고려하지 않는다.
이 사진도 도움이 될 것 같습니다.격리 레벨의 차이를 빨리 기억하고 싶을 때 참고가 됩니다(유튜브의 kudbenkat 덕분에).
반복 가능한 읽기에서 반복 가능한 것은 테이블 전체가 아닌 태플에 관한 것입니다.ANSC 분리 수준에서는 팬텀 판독 이상이 발생할 수 있습니다. 즉, 같은 표에서 절이 두 번이면 다른 결과 세트를 반환할 수 있습니다.말 그대로, 반복할 수 없어요.
여기에는 다른 답변이 있지만 기본 데이터베이스 아키텍처에 대한 자세한 내용은 나와 있지 않습니다. 따라서 트랜잭션 분리 수준이 어떻게 기능하는지, 어떤 문제가 해결되는지 이해하기 어렵습니다.
동시 환경에서의 일반적인 문제의 개요
데이터베이스 시스템에서는 여러 연결을 동시에 사용할 수 있습니다.이로 인해 다른 동시 시스템에서 볼 수 있는 것과 같은 종류의 문제가 발생합니다.예를 들어 멀티스레드 환경에서 뮤텍스는 메모리에 대한 동시 액세스를 방해하므로 데이터가 손상되거나 유효하지 않은 레이스 조건 문제가 해결됩니다.
마찬가지로 데이터베이스 시스템에서 동시 CRUD 작업(업데이트, 삽입, 삭제, 선택)을 허용하기 때문에 여러 연결에 의한 동시 작업이 바람직하지 않은 동작을 일으킬 수 있습니다.
데이터베이스 행 조작의 원자성은 완전한 데이터 파손이나 불일치를 방지하므로 항상 트랜잭션 격리의 기본 레벨이 적용됩니다.
자세한 내용은 ACID(원자, 일관성, 절연, 내구성)를 참조하십시오.간단히 설명하자면, 행 단위로 운영은 원자적이라는 것입니다.즉, 한 접속이 같은 행에 데이터를 부분적으로 쓰기 때문에 다른 접속이 데이터를 손상시키기 전에 행 데이터의 일부를 쓰는 상황을 방지함으로써 데이터 손상을 방지합니다(멀티스레드 환경에 익숙한 사용자는 이를 보다 직관적으로 이해할 수 있습니다).
위에서 설명한 문제는 멀티스레드 프로그래밍에서 볼 수 있는 문제와 관련이 있습니다.이 문제는 첫 번째 스레드가 완료되기 전에 다른 스레드가 메모리 블록에 쓰기를 시작하고 같은 블록에 데이터를 부분적으로 쓰는 것입니다.이로 인해 데이터가 일관되지 않게 됩니다.
행 연산은 기본적인 보호 수준을 이미 제공하기 때문에 먼저 행 연산의 원자적 특성을 이해하는 것이 중요합니다.
트랜잭션 격리 수준 유형
MariaDB 및 기타 많은 SQL 데이터베이스 구현에서 사용할 수 있는 트랜잭션 격리 수준에 대해 알아보겠습니다.
먼저 다른 격리 수준이 무엇인지 알아야 합니다.
- 커밋되지 않은 읽기
- 읽기 커밋
- 반복 가능한 읽기
- 시리얼화 가능
트랜잭션 격리 수준에서는 어떤 문제가 해결됩니까?
이러한 다양한 옵션의 기능을 설명하기 전에 각 옵션에 의해 해결되는 문제를 이해하는 것이 중요합니다.다음은 잠재적인 원치 않는 행동 목록입니다.
- 더티 읽기
- 반복할 수 없는 읽기
- 팬텀 읽기
더티 읽기:
데이터베이스 작업은 종종 트랜잭션으로 그룹화됩니다.그런 다음 이 트랜잭션은 작업 그룹으로 데이터베이스에 커밋되거나 롤백이 수행되어 작업 그룹을 폐기합니다.
한 Connection이 트랜잭션으로 일련의 작업을 시작하고 두 번째 Connection이 동일한 테이블에서 데이터를 읽기 시작하면 두 번째 Connection은 커밋된 데이터를 데이터베이스에서 읽거나 열린 트랜잭션의 일부로 수행된 변경 사항을 읽을 수 있습니다.
이는 읽기 커밋됨과 읽기 커밋되지 않음의 차이를 정의합니다.
커밋되지 않은 데이터를 읽는 것이 의미가 없는 경우가 많기 때문에 이는 개념적으로 이례적입니다.트랜잭션의 전체 목적은 데이터베이스의 데이터가 이러한 방식으로 변경되지 않도록 하는 것입니다.
요약:
- Connection A가 트랜잭션을 열고 수정(쓰기) 작업을 큐잉하기 시작합니다.
- 연결 B가 읽기 커밋되지 않은 모드로 열리고 데이터베이스에서 데이터를 읽습니다.
- 접속 A는 추가 변경 큐잉을 계속한다.
- Connection B가 데이터를 다시 읽으면 변경된 것입니다.
- Connection A가 롤백을 실행하고 Connection B가 다른 판독을 실행하는 경우 커밋되지 않은 데이터의 롤백으로 인해 데이터 판독이 변경됩니다.
- 이것은 더러운 읽기라고 알려져 있다.
- 일반적으로 읽기 커밋되지 않은 모드로 작업하면 트랜잭션이 존재하지 않는 것처럼 보이기 때문에 이 문제는 걱정할 필요가 없습니다.
반복할 수 없는 읽기
위의 경우 읽기 작업 모드가 "Read Committed"로 설정된 경우 반복 불가능한 읽기가 발생할 수 있습니다.이 모드는 커밋된 데이터만 읽기 때문에 더티 읽기 문제를 해결합니다.
사용 가능한 쓰기 조작은 다음과 같습니다.
- 갱신하다
- 삽입하다
- 삭제하다
Non-Repeatable Read는 읽기 작업이 행 집합을 읽은 다음 작업을 반복하고 동일한 행 집합(같은 키)이 반환될 때 발생하지만 키가 아닌 데이터가 변경되었습니다.
예를 들어 다음과 같습니다.
- Connection A: 접속 A로 하겠습니다.를 들어 과 같은에 따라 됩니다.
where
절을 클릭합니다. - 연결 B는 이 세트의 하나 이상의 행과 다른 행을 변경할 수 있습니다.
- Connection A가 동일한 읽기 쿼리를 반복하면 동일한 행 세트가 반환되지만 "키"의 일부가 아닌 데이터가 변경되었을 수 있습니다.
- '는 '키'의 됩니다.
where
절, "" " " " " " " " , " 입니다.
팬텀 읽기
이치노 안insert
★★★★★★★★★★★★★★★★★」delete
작업을 수행하면 반환된 행 집합에서 반환된 행이 변경될 수 있습니다.삽입 작업은 반환된 행 집합에 새 행을 추가할 수 있습니다.삭제 조작은 반대로 행이 반환되는 일련의 행에서 행을 삭제할 수 있습니다.
요약:
- 연결 A가 읽기 작업을 수행합니다.
- 연결 B가 삽입 또는 삭제 작업을 수행합니다.
- Connection A는 동일한 읽기 작업을 수행하므로 다른 행 세트가 반환됩니다.새 행이 나타날 수 있습니다.기존 행이 사라질 수 있습니다.그래서 "유령"을 읽는다.
분리 수준
잠재적인 바람직하지 않은 행동에 대한 이해를 바탕으로 격리 수준은 다음과 같이 작동합니다.
- 커밋되지 않은 읽기 기능은 이러한 문제를 예방하는 데 아무런 도움이 되지 않습니다.그러나 원자 행 조작으로 인해 기본 수준의 보호는 여전히 존재합니다.
- 읽기를 커밋하면 더러운 읽기만 방지됩니다.
- 반복 가능 읽기는 더티 읽기 및 비반복 가능 읽기를 방지하지만 팬텀 읽기는 방지하지 않습니다.
- 시리얼화 가능은 위의 모든 것을 방지합니다.
격리 수준이 높을수록 데이터베이스의 더 많은 데이터를 "잠금"하여 동시 액세스를 방지해야 합니다.DMBS가 테이블 전체를 잠그고 있는 경우 다른 연결에서는 해당 데이터를 수정할 수 없기 때문에 바람직하지 않을 수 있습니다.이로 인해 데이터베이스에 액세스해야 하는 다른 프로세스가 중단될 수 있습니다.
Read Committed는 일반적으로 가장 합리적인 선택입니다.그러면 데이터베이스 관리자가 커밋된 데이터(일시적이지 않고 영속적인 데이터)만 볼 수 있으며 다른 프로세스가 중단되지 않습니다.
참고 문헌
추가 정보:
Geeks for Geeks Isolation Levels. (읽기 커밋된 데이터의 읽기가 커밋된다는 등의 설명 등 일부 정보는 의미가 없습니다.그것은 옳지 않고 말이 되지 않는다.커밋되지 않은 데이터는 명시적인 커밋 조작에 의해서만 커밋됩니다).
SQL Server에서 분리 수준은 트랜잭션이 제공하는 데이터 일관성 및 동시성 수준을 결정합니다.SQL Server에서는 Read Committed 및 Repeatable Read를 포함하여 다양한 분리 수준을 사용할 수 있습니다.여기에서는 예를 들어 보겠습니다.
Read Committed Isolation Level: Read Committed는 SQL Server의 기본 분리 수준입니다.이 분리 수준에서는 각 트랜잭션에서 커밋된 데이터만 볼 수 있습니다.트랜잭션은 데이터를 읽을 때 트랜잭션이 완료될 때까지 데이터에 대한 공유 잠금을 획득합니다.이렇게 하면 현재 트랜잭션이 완료될 때까지 다른 트랜잭션이 데이터를 수정할 수 없습니다.그러나 다른 트랜잭션은 동일한 데이터를 읽을 수 있지만 현재 트랜잭션이 커밋될 때까지 변경 내용을 볼 수 없습니다.
예를 들어 다음과 같은 시나리오를 생각해 보겠습니다.
트랜잭션 1은 테이블 A에서 데이터를 읽고 동일한 데이터를 갱신한다.트랜잭션 2는 테이블 A에서 데이터를 읽습니다.
읽기 커밋 분리 수준에서 트랜잭션 1은 데이터를 업데이트할 때 데이터에 대한 공유 잠금을 획득합니다.트랜잭션2는 데이터를 읽을 수 있지만 커밋될 때까지 트랜잭션1에 의한 변경은 표시되지 않습니다.트랜잭션 1이 커밋되면 트랜잭션 2는 업데이트된 데이터를 읽을 수 있습니다.
반복 가능한 읽기 분리 수준: 반복 가능한 읽기는 읽기 커밋됨보다 높은 분리 수준입니다.이 분리 수준에서 트랜잭션은 읽은 모든 데이터에 대한 공유 잠금을 획득하고 트랜잭션이 완료될 때까지 잠금을 유지합니다.이렇게 하면 현재 트랜잭션이 완료될 때까지 다른 트랜잭션이 데이터를 수정하거나 삭제할 수 없습니다.
예를 들어 다음과 같은 시나리오를 생각해 보겠습니다.
트랜잭션 1은 테이블 A와 테이블 B에서 데이터를 읽는다.트랜잭션 2는 테이블 B에 데이터를 삽입합니다.
반복 가능한 읽기 분리 수준에서 트랜잭션 1은 테이블 A 및 테이블 B에서 데이터를 읽을 때 읽은 모든 데이터에 대한 공유 잠금을 획득합니다.트랜잭션2가 테이블B에 데이터를 삽입하려고 하면 트랜잭션1에 의해 취득된 공유 잠금에 의해 차단됩니다.트랜잭션 1이 완료되고 테이블 B에 대한 공유 잠금을 해제할 때까지 삽입 작업이 허용되지 않습니다.
읽기 커밋된 읽기와 반복 가능한 읽기의 차이:Read Committed와 Repeatable Read 분리 수준의 주요 차이점은 트랜잭션에 의해 취득되는 잠금 유형입니다.읽기 커밋 분리 수준에서는 트랜잭션이 읽은 데이터에 대한 공유 잠금을 획득하지만 데이터가 더 이상 필요하지 않게 되면 바로 잠금을 해제합니다.반복 가능한 읽기 분리 수준에서는 트랜잭션이 읽은 모든 데이터에 대한 공유 잠금을 획득하고 트랜잭션이 완료될 때까지 잠금을 유지합니다.
또 다른 차이점은 반복 가능한 읽기 분리 수준에서는 트랜잭션이 동일한 데이터를 여러 번 읽을 수 있고 항상 동일한 데이터를 볼 수 있다는 것입니다.읽기 커밋 분리 수준에서 트랜잭션은 동일한 데이터를 여러 번 읽을 수 있지만 다른 트랜잭션이 읽기 사이의 데이터를 수정하는 경우 다른 데이터를 볼 수 있습니다.
결론:결론적으로 SQL Server의 분리 수준에 따라 트랜잭션이 제공하는 데이터의 일관성 및 동시성 수준이 결정됩니다.Read Committed Read와 Repeatable Read는 잠금 동작이 다른 두 가지 분리 수준입니다.Read Committed는 읽기 데이터에 대한 공유 잠금을 취득하여 데이터가 더 이상 필요하지 않게 되면 즉시 잠금을 해제함으로써 일관성을 제공합니다.Repeatable Read는 읽어들인 모든 데이터에 대한 공유 잠금을 취득하여 트랜잭션이 완료될 때까지 유지함으로써 더욱 강력한 일관성을 제공합니다.격리 수준의 선택은 애플리케이션의 특정 요건과 일관성과 동시성 간의 균형에 따라 달라집니다.
초기 수용 솔루션에 대한 나의 관찰.
RR (default mysql) - tx가 열려 있고 SELECT가 실행된 경우 이전 tx가 커밋될 때까지 다른 tx는 이전 READ 결과 세트에 속하는 행을 삭제할 수 없습니다(실제로 새로운 tx의 delete 문은 정지합니다). 단, 다음 tx는 문제없이 테이블에서 모든 행을 삭제할 수 있습니다.이전 tx의 다음 READ에서는 커밋될 때까지 오래된 데이터가 계속 표시됩니다.
언급URL : https://stackoverflow.com/questions/4034976/difference-between-read-commited-and-repeatable-read-in-sql-server
'programing' 카테고리의 다른 글
전화로 확인할 때 확인MongoDB 컬렉션의 인덱스? (0) | 2023.05.07 |
---|---|
첫 번째 커밋을 어떻게 다시 시작합니까? (0) | 2023.05.07 |
LEFT OUTER JOIN이 왼쪽 테이블에 있는 것보다 더 많은 레코드를 반환하려면 어떻게 해야 합니까? (0) | 2023.04.07 |
SQL Server Management Studio에서 SQL 포맷 (0) | 2023.04.07 |
Visual Studio 기능에 대한 IntelliSense 코멘트를 받는 방법 (0) | 2023.04.07 |