쓰기 및 읽기/쓰기 작업
다양한 형식의 명령을 언제 어떻게 실행할지 결정하면 동시 쓰기 및 읽기-쓰기 작업의 특정 동작을 관리할 수 있습니다. 이 논의와 관련된 명령은 다음과 같습니다.
-
COPY 명령 - 로드를 수행(초기 또는 증분적 로드)
-
INSERT 명령 - 하나 이상의 행을 한 번에 추가
-
UPDATE 명령 - 기존 행을 수정
-
DELETE 명령 - 행을 제거
COPY 및 INSERT 작업은 순수한 쓰기 작업이지만 DELETE 및 UPDATE 작업은 읽기/쓰기 작업입니다. (행을 삭제 또는 업데이트하려면 먼저 행을 읽어야 합니다.) 동시 쓰기 작업의 결과는 동시에 실행 중인 특정 명령에 따라 달라집니다. 동일 테이블에 대한 COPY 및 INSERT 작업은 잠금이 풀릴 때까지 대기 상태로 보류되었다가 정상적으로 진행됩니다.
UPDATE 작업과 DELETE 작업은 쓰기를 수행하기 전에 초기 테이블 읽기에 의존하므로 서로 다르게 동작합니다. 동시 트랜잭션은 서로에게 보이지 않으므로 UPDATE와 DELETE 모두 마지막 커밋으로부터 데이터 스냅샷을 읽어야 합니다. 첫 번째 UPDATE 또는 DELETE가 잠금을 풀면 두 번째 UPDATE 또는 DELETE는 작업할 데이터가 잠재적으로 부실한지 여부를 확인해야 합니다. 데이터는 부실해지지 않는데, 첫 번째 트랜잭션이 잠금을 풀 때까지 두 번째 트랜잭션은 데이터의 스냅샷을 가져오지 않기 때문입니다.
동시 쓰기 트랜잭션의 잠재적 교착 상황
트랜잭션에 둘 이상의 테이블의 업데이트가 포함되는 경우, 동시에 실행되는 두 트랜잭션이 같은 테이블 세트에 쓰기를 시도하다 교착될 가능성이 늘 존재합니다. 트랜잭션은 커밋하거나 롤백할 때 테이블 잠금을 한 번에 하나씩 풀지 않고 모든 잠금을 한 번에 풉니다.
예를 들어 트랜잭션 T1과 T2가 대략 같은 시간에 시작된다고 가정해 보십시오. T1이 테이블 A에 쓰기를 시작하고 T2가 테이블 B에 쓰기를 시작하는 경우, 두 트랜잭션은 충돌 없이 진행될 수 있습니다. 하지만 T1이 테이블 A에 대한 쓰기를 마치고 테이블 B에 대한 쓰기를 시작해야 하는 경우에는 T2가 아직 테이블 B를 잠그고 있기 때문에 계속 진행할 수 없습니다. 반대로 T2가 테이블 B에 대한 쓰기를 마치고 테이블 A에 대한 쓰기를 시작해야 하는 경우, T1이 테이블 A를 잠그고 있기 때문에 계속 진행할 수 없습니다. 어느 트랜잭션도 쓰기 작업이 커밋될 때까지 잠금을 풀 수 없으므로 어느 트랜잭션도 진행될 수 없는 것입니다.
이런 종류의 교착을 피하기 위해서는 동시 쓰기 작업을 신중하게 예약해야 합니다. 예를 들어 트랜잭션에서 항상 같은 순서로 테이블을 업데이트해야 하며, 잠금을 지정하는 경우에는 DML 작업을 수행하기 전에 같은 순서로 테이블을 잠가야 합니다.