이 문서는 지원되지 않는 버전의 PostgreSQL 용입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다PostgreSQL : 문서 : 17 : 13.2. 무지개 토토 격리버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

12.2. 거래 격리

SQL표준 정의 세 가지 현상 측면에서 4 가지 수준의 거래 격리 이는 동시 거래 사이에서 방지해야합니다. 이것들 바람직하지 않은 현상은 다음과 같습니다.

더러운 읽기

사설 토토은 동시에 작성된 데이터를 읽습니다 커밋되지 않은 거래.

반복 할 수없는 읽기

트랜잭션은 이전에 읽은 데이터를 다시 읽습니다 데이터가 다른 트랜잭션에 의해 수정되었음을 발견합니다 (처음 읽은 이후로 커밋 된).

Phantom Read

사설 토토은 쿼리 세트를 반환합니다 검색 조건을 만족시키고 세트를 찾는 행 다른 때문에 조건을 만족시키는 줄의 최근에 커뮤니케이션 거래.

4 개의 거래 격리 수준과 해당 행동은에 설명되어 있습니다.테이블 12-1.

표 12-1.SQL거래 격리 수준

격리 레벨 더러운 읽기 반복 할 수없는 읽기 Phantom Read
커밋되지 않은 읽기 가능 가능 가능
Committed 불가능 가능 가능
반복 가능한 읽기 불가능 불가능 가능
SERIALIZALE 불가능 불가능 불가능

inPostgreSQL, 가능합니다 4 개의 표준 트랜잭션 격리 수준 중 하나를 요청하십시오. 그러나 내부적으로는 두 가지 별개의 격리 수준 만 있습니다. 커밋되고 직렬화 가능한 레벨에 해당합니다. 레벨을 선택하면 커밋되지 않은 읽기를 선택하면 실제로 읽을 수 있습니다. 커밋하고 반복 가능한 읽기를 선택하면 정말로 얻을 수 있습니다. 직렬화 가능하므로 실제 분리 수준은보다 엄격 할 수 있습니다. 당신이 선택한 것. 이것은 SQL 표준 : 4에 의해 허용됩니다 격리 수준은 어떤 현상이 발생하지 않아야하는지 정의합니다. 그들은 어떤 현상이 일어나야하는지 정의하지 않습니다. 그 이유PostgreSQL두 개만 제공합니다 격리 수준은 이것이 유일하게 현명한 방법이라는 것입니다. Multiversion 동시성 제어에 대한 표준 격리 수준 건축학. 이용 가능한 격리 수준의 동작은 다음과 같습니다 다음 하위 섹션에 자세히 설명합니다.

거래의 거래 격리 수준을 설정하려면 사용 명령세트 거래.

12.2.1. 헌신적 인 격리를 읽으십시오 수준

Committed기본값입니다 격리 수준에서PostgreSQL. 사설 토토 이이 격리 수준에서 실행되면 Aselect쿼리는 이전에 커밋 된 데이터 만 볼 수 있습니다 쿼리가 시작되었습니다. 커밋되지 않은 데이터 나 변경을 볼 수 없습니다 동시 트랜잭션에 의해 쿼리 실행 중에 커밋. (그러나select이전 업데이트의 효과 자체 내에서 실행되었습니다 거래는 아직 커밋되지 않았음에도 불구하고.) 효과, Aselect쿼리에는 스냅 샷이 나타납니다 해당 쿼리가 시작되는 순간에 데이터베이스의 달리다. 두 가지 연속select명령은 다른 데이터를 볼 수 있습니다. 다른 사설 토토이 변경되는 경우 단일 사설 토토 첫 번째 실행select.

업데이트, 삭제, 선택 업데이트공유 선택명령은와 동일하게 행동합니다selectin 대상 행 검색 조건 : 대상 만 찾을 수 있습니다. 명령 시작 시간에 따라 커밋 된 행. 하지만, 이러한 대상 행은 이미 업데이트되었거나 삭제되었거나 잠금) 다른 동시 거래에 의해 설립하다. 이 경우 업데이트가 커밋 또는 롤백을 위해 트랜잭션을 최초로 업데이트합니다 ( 아직 진행 중). 첫 번째 업데이트가 롤백되면, 그것 효과가 무효화되고 두 번째 업데이트는 다음과 같이 진행할 수 있습니다. 원래 발견 된 행을 업데이트합니다. 첫 번째 업데이터 인 경우 커밋, 두 번째 업데이터는 첫 번째 경우 행을 무시합니다. Updater는 삭제했습니다. 그렇지 않으면 적용하려고합니다. 행의 업데이트 버전으로 작동합니다. 검색 명령 조건 (여기서절)이 업데이트 된 버전이 행은 여전히 검색 조건과 일치합니다. 그렇다면 두 번째 업데이트는 업데이트에서 시작하여 작동을 진행합니다 행의 버전. (의 경우선택 updateand공유 선택, 그것은 잠긴 행의 업데이트 버전임을 의미합니다. 그리고 클라이언트로 돌아 왔습니다.)

위 규칙으로 인해 업데이트가 가능합니다. 일관되지 않은 스냅 샷을 보도록 명령 : 효과를 볼 수 있습니다. 동시에 같은 행에 영향을 미치는 동시 업데이트 명령 업데이트를 시도하고 있지만 그 효과는 보이지 않습니다. 데이터베이스의 다른 행에 대한 명령. 이 행동이 만듭니다 관련된 명령에 부적합한 커밋 된 모드를 읽습니다 복잡한 검색 조건. 그러나 그것은 옳습니다 더 간단한 경우. 예를 들어, 은행 잔액 업데이트를 고려하십시오 와 같은 거래와 함께

시작;
업데이트 계정 설정 밸런스 = 밸런스 + 100.00 여기서 acctnum = 12345;
업데이트 계정 설정 밸런스 = 밸런스 -100.00 여기서 acctnum = 7534;
저지르다;

그러한 거래가 동시에 변경하려고한다면 계정 잔액 12345, 우리는 분명히 두 번째를 원합니다 계정의 업데이트 된 버전에서 시작하는 거래 열. 각 명령은 미리 결정된 것만 영향을 미치기 때문입니다 행, 행의 업데이트 된 버전을 보자 번거로운 불일치를 만듭니다.

읽기 커밋 된 모드에서 각 새로운 명령은 모든 거래를 포함하는 새로운 스냅 샷 동일한 거래에서 그 순간, 후속 명령은 그럴 것입니다 헌신적 인 동시 거래의 효과를 확인하십시오. 사례. 여기서 문제가되는 요점은 A 내에 있는지 여부입니다.단일우리가 보는 명령 데이터베이스의 절대적으로 일관된 관점.

Read Commited에 의해 제공되는 부분 트랜잭션 격리 모드는 많은 응용 프로그램에 적합 하며이 모드는 빠릅니다. 사용하기 간단합니다. 그러나 복잡한 응용 프로그램의 경우 쿼리 및 업데이트, 더 많은 것을 보장해야 할 수도 있습니다. 읽기보다 데이터베이스에 대한 엄격하게 일관된보기 커밋 된 모드 제공.

12.2.2. 직렬화 가능한 분리 수준

레벨SERIALIZALE제공 가장 엄격한 트랜잭션 격리. 이 레벨은 연재물을 모방합니다 트랜잭션 실행은 마치 트랜잭션이 실행 된 것처럼 거래됩니다 동시에 일련의 것이 아니라 연속적으로. 하지만, 이 레벨을 사용하는 응용 프로그램은 다시 시도해야합니다 직렬화 실패로 인한 거래.

거래가 직렬화 가능한 수준에있을 때 AselectQuery는 커밋 된 데이터 만 볼 수 있습니다 거래가 시작되기 전에; 커밋되지 않은 것을 보지 못합니다 사설 토토 실행 중에 커밋 된 데이터 또는 변경 동시 거래. (그러나select이전 업데이트의 효과가 나타납니다 비록 자체 거래 내에서 실행됩니다. 아직 헌신적입니다.) 이것은 저지른 읽기와 다릅니다. 그만큼select현재 시작이 아닌 거래 시작 거래 내의 쿼리. 따라서 연속select단일 트랜잭션 내에서 명령 항상 같은 데이터를보십시오.

업데이트, 삭제, 선택을 선택하십시오 업데이트공유 선택명령은와 동일하게 행동합니다.selectin 대상 행 검색 조건 : 대상 만 찾을 수 있습니다. 트랜잭션 시작 시간에 따라 커밋 된 행. 그러나 이러한 대상 행은 이미 업데이트되었을 수 있습니다 (또는 다른 동시 거래에 의해 삭제 또는 잠금) 시간이 발견됩니다. 이 경우 직렬화 가능한 트랜잭션 첫 번째 업데이트 트랜잭션이 커밋 또는 롤을 기다릴 때까지 기다립니다. 뒤로 (아직 진행중인 경우). 첫 번째 업데이트가 굴리는 경우 뒤로, 그 효과는 무효화되고 직렬화 가능합니다 트랜잭션은 원래 발견 된 행을 업데이트하여 진행할 수 있습니다. 그러나 첫 번째 업데이트가 커밋하는 경우 (그리고 실제로 업데이트되었거나 잠긴 것이 아니라 행을 삭제했습니다. 트랜잭션은 메시지와 함께 롤백됩니다

오류 : 동시 업데이트로 인해 액세스를 직렬화 할 수 없습니다

직렬화 가능한 트랜잭션은 수정하거나 잠금 할 수 없기 때문입니다 직렬화 가능한 후 다른 거래에 의해 행이 변경되었습니다 거래가 시작되었습니다.

응용 프로그램 이이 오류 메시지를 받으면해야합니다 현재 거래를 중단 한 다음 전체를 다시 시도하십시오 처음부터 거래. 두 번째로 거래는 이전에 커밋 된 변화를 그 일부로보고 있습니다 데이터베이스의 초기보기이므로 논리적 충돌이 없습니다. 새 버전의 행을 시작점으로 사용합니다. 새로운 트랜잭션의 업데이트.

거래 만 업데이트하는 것만 재조정해야 할 수도 있습니다. 읽기 전용 트랜잭션에는 직렬화가 없습니다 갈등.

직렬화 가능한 모드는 엄격한 보증을 제공합니다 각 트랜잭션은 데이터베이스의 전적으로 일관된 관점을 보게됩니다. 그러나 응용 프로그램은 다시 시도해야합니다 동시 업데이트가 불가능할 때 거래 직렬 실행의 환상을 유지하십시오. 비용 이후 복잡한 트랜잭션을 재조정하는 것이 중요 할 수 있습니다.이 모드는이 모드입니다 트랜잭션을 업데이트 할 때만 논리가 포함 된 경우에만 권장됩니다 읽기에서 잘못된 답변을 줄 수있을 정도로 충분히 복잡합니다. 커밋 된 모드. 가장 일반적으로 직렬화 가능한 모드가 필요합니다 거래가 몇 가지 연속 명령을 실행할 때 데이터베이스의 동일한보기를 봐야합니다.

12.2.2.1. 직렬화 가능한 분리 대표적 일련화 가능성

직관적 인 의미 (및 수학적 정의)의"Serializable"실행입니다 성공적으로 커밋 된 두 개의 동시 거래는 그럴 것입니다 이후에 하나의 연속적으로 엄격하게 실행 된 것으로 보입니다 기타 - 먼저 발생하는 것처럼 보였지만 미리 예측 가능. 그것을 실현하는 것이 중요합니다 나열된 바람직하지 않은 행동 금지표 12-1is 진정한 직렬화 가능성을 보장하기에 충분하지 않으며 실제로PostgreSQL'S 직렬화 가능 방법보장하지 않습니다 이러한 의미에서 일련의 실행. 예를 들어, 테이블 고려Mytab, 초기에 포함

클래스 | 값 
-------+-------
     1 |    10
     1 |    20
     2 |   100
     2 |   200

직렬화 가능한 트랜잭션이 계산된다고 가정합니다

mytab에서 sum (value)을 선택하여 클래스 = 1;

그런 다음 결과 (30)을로 삽입합니다.value새 행으로클래스= 2. 동시에 직렬화 가능합니다 거래 B 계산

mytab에서 sum (value)을 선택하여 클래스 = 2;

결과 300을 얻습니다. 와 함께클래스= 1. 그런 다음 둘 다 거래 커밋. 나열된 바람직하지 않은 행동은 없습니다 발생했지만 우리는 가질 수없는 결과가 있습니다. 일련의 순서 중 어느 쪽이든 발생했습니다. A가 전에 실행 된 경우 B, B는 300이 아닌 합계 330을 계산했을 것입니다. 다른 순서는 다른 합계를 초래했을 것입니다. A에 의해 계산

진정한 수학적 직렬화 가능성을 보장하기 위해 데이터베이스 시스템이 시행하는 데 필요합니다술어 잠금사설 토토은 일치여기서a 다른 동시 거래에서 쿼리. 예를 들어, 한 번 사설 토토 A가 쿼리를 실행했습니다선택 ... 여기서 클래스 = 1, a 술어 잠금 시스템은 트랜잭션 B를 금지합니다 A가 커밋 될 때까지 클래스 1에 새 행을 삽입합니다.[1]잠금 시스템은 구현하기에 복잡하고 극도로 복잡합니다 모든 세션은 모든 동시에 실행 된 모든 쿼리의 세부 사항 거래. 그리고이 많은 비용은 그 이후로 대부분 낭비됩니다 실제로 대부분의 응용 프로그램은 일종의 일을하지 않습니다. 문제가 발생할 수 있습니다. (확실히 위의 예 오히려 진실하고 실제 소프트웨어를 대표 할 가능성은 거의 없습니다.) 이러한 이유로postgresql는 술어를 구현하지 않습니다 잠금.

이 경우 비 정기화 가능성이있는 경우 실행은 진정한 위험이며 문제를 예방할 수 있습니다. 명시 적 잠금의 적절한 사용. 추가 토론 다음 섹션에 나타납니다.

노트

[1]

본질적으로, 술어 잠금 시스템은 팬텀을 방지합니다 MVCC는 쓰여진 내용을 제한하여 읽습니다 읽은 내용을 제한하여.