SET TRANSACTION

SET TRANSACTION (SET TRANSACTION)

현재 트랜잭션의 특성을 설정하는 명령이에요. 격리 수준(isolation level), 접근 모드(읽기/쓰기 또는 읽기 전용), deferrable 모드 같은 걸 트랜잭션마다 설정할 수 있어요. SET SESSION CHARACTERISTICS는 세션의 이후 트랜잭션에 적용될 기본값을 설정하고, SET TRANSACTION SNAPSHOT은 기존 트랜잭션의 스냅샷을 가져와 새 트랜잭션을 실행하게 해 줍니다.

출처: PostgreSQL 문서

본문

개요 (Synopsis)

SET TRANSACTION transaction_mode [, ...]
SET TRANSACTION SNAPSHOT snapshot_id
SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]

여기서 transaction_mode는 다음 중 하나예요:

    ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
    READ WRITE | READ ONLY
    [ NOT ] DEFERRABLE

설명 (Description)

SET TRANSACTION 명령은 현재 트랜잭션의 특성을 설정해요. 이후의 어떤 트랜잭션에도 영향을 주지 않아요. SET SESSION CHARACTERISTICS는 세션의 이후 트랜잭션에 대한 기본 트랜잭션 특성을 설정해요. 이 기본값은 개별 트랜잭션에 대해 SET TRANSACTION으로 덮어쓸 수 있어요.

사용 가능한 트랜잭션 특성은 트랜잭션 격리 수준, 트랜잭션 접근 모드(읽기/쓰기 또는 읽기 전용), deferrable 모드예요. 또한 스냅샷을 선택할 수 있는데, 이는 세션 기본값이 아니라 현재 트랜잭션에만 해당해요.

트랜잭션의 격리 수준은 다른 트랜잭션이 동시에 실행 중일 때 그 트랜잭션이 볼 수 있는 데이터를 결정해요:

  • READ COMMITTED — 문장은 자신이 시작되기 전에 커밋된 행만 볼 수 있어요. 기본값이에요.
  • REPEATABLE READ — 현재 트랜잭션의 모든 문장은 이 트랜잭션에서 첫 번째 쿼리나 데이터 수정 문장이 실행되기 전에 커밋된 행만 볼 수 있어요.
  • SERIALIZABLE — 현재 트랜잭션의 모든 문장은 이 트랜잭션에서 첫 번째 쿼리나 데이터 수정 문장이 실행되기 전에 커밋된 행만 볼 수 있어요. 동시 serializable 트랜잭션 사이의 읽기·쓰기 패턴이, 그 트랜잭션들을 serial(하나씩) 실행했다면 발생할 수 없었을 상황을 만들면, 그중 하나가 serialization_failure 오류와 함께 롤백돼요.

SQL 표준은 READ UNCOMMITTED라는 추가 수준을 하나 더 정의해요. PostgreSQL에서 READ UNCOMMITTEDREAD COMMITTED로 취급돼요.

트랜잭션 격리 수준은 트랜잭션의 첫 번째 쿼리나 데이터 수정 문장(SELECT, INSERT, DELETE, UPDATE, MERGE, FETCH, 또는 COPY)이 실행된 후에는 바꿀 수 없어요. 트랜잭션 격리와 동시성 제어에 대한 자세한 내용은 Chapter 13을 참고하세요.

트랜잭션 접근 모드는 트랜잭션이 읽기/쓰기인지 읽기 전용인지 결정해요. 읽기/쓰기가 기본값이에요. 트랜잭션이 읽기 전용일 때는 다음 SQL 명령들이 허용되지 않아요: INSERT, UPDATE, DELETE, MERGE, 그리고 쓰려는 테이블이 임시 테이블이 아닌 경우 COPY FROM; 모든 CREATE, ALTER, DROP 명령; COMMENT, GRANT, REVOKE, TRUNCATE; 그리고 실행하려는 명령이 위에 나열된 것들 중 하나라면 EXPLAIN ANALYZEEXECUTE. 이는 핵심적인 읽기 전용 개념으로, 디스크에 대한 모든 쓰기를 막지는 않아요.

DEFERRABLE 트랜잭션 속성은 트랜잭션이 SERIALIZABLE이면서 READ ONLY일 때만 효과가 있어요. 트랜잭션에 이 세 속성이 모두 선택되면, 그 트랜잭션은 처음 스냅샷을 획득할 때 블록될 수 있고, 그 후에는 일반 SERIALIZABLE 트랜잭션의 오버헤드 없이, 그리고 serialization 실패에 기여하거나 취소될 위험 없이 실행될 수 있어요. 이 모드는 오래 실행되는 보고서나 백업에 잘 맞아요.

SET TRANSACTION SNAPSHOT 명령은 기존 트랜잭션과 같은 스냅샷으로 새 트랜잭션을 실행할 수 있게 해 줍니다. 사전에 존재하는 트랜잭션은 pg_export_snapshot 함수로 스냅샷을 내보내야 해요 (see Section 9.28.5). 그 함수는 스냅샷 식별자를 반환하는데, 이를 SET TRANSACTION SNAPSHOT에 주어 어떤 스냅샷을 가져올지 지정해야 해요. 이 명령에서는 식별자를 문자열 리터럴로 써야 해요, 예: '00000003-0000001B-1'. SET TRANSACTION SNAPSHOT은 트랜잭션 시작 시점, 트랜잭션의 첫 번째 쿼리나 데이터 수정 문장(SELECT, INSERT, DELETE, UPDATE, MERGE, FETCH, 또는 COPY) 전에만 실행할 수 있어요. 게다가 트랜잭션은 이미 SERIALIZABLE이나 REPEATABLE READ 격리 수준으로 설정되어 있어야 해요(그렇지 않으면, READ COMMITTED 모드가 각 명령마다 새 스냅샷을 취하므로 스냅샷이 즉시 버려질 거예요). 가져오는 트랜잭션이 SERIALIZABLE 격리 수준을 사용하면, 스냅샷을 내보낸 트랜잭션도 같은 격리 수준을 사용해야 해요. 또한 non-read-only serializable 트랜잭션은 읽기 전용 트랜잭션에서 스냅샷을 가져올 수 없어요.

참고 (Notes)

선행하는 START TRANSACTION이나 BEGIN 없이 SET TRANSACTION을 실행하면 경고가 나오고 그 외에는 아무 효과가 없어요.

SET TRANSACTION을 쓰지 않고 BEGIN이나 START TRANSACTION에서 원하는 *transaction_modes*를 지정할 수도 있어요. 다만 그 옵션은 SET TRANSACTION SNAPSHOT에는 사용할 수 없어요.

세션 기본 트랜잭션 모드는 구성 파라미터 default_transaction_isolation, default_transaction_read_only, default_transaction_deferrable로도 설정하거나 조사할 수 있어요. (실제로 SET SESSION CHARACTERISTICS는 이 변수들을 SET으로 설정하는 장황한 동치일 뿐이에요.) 즉 기본값은 설정 파일에서, ALTER DATABASE 등으로 설정할 수 있어요. 자세한 내용은 Chapter 19를 참고하세요.

현재 트랜잭션의 모드도 구성 파라미터 transaction_isolation, transaction_read_only, transaction_deferrable로 설정하거나 조사할 수 있어요. 이 파라미터 중 하나를 설정하는 것은 해당 SET TRANSACTION 옵션과 같은 방식으로 동작하며, 언제 할 수 있는지에 대한 같은 제한이 적용돼요. 다만 이 파라미터들은 설정 파일이나 라이브 SQL 외의 어떤 소스에서도 설정할 수 없어요.

예시 (Examples)

이미 존재하는 트랜잭션과 같은 스냅샷으로 새 트랜잭션을 시작하려면, 먼저 기존 트랜잭션에서 스냅샷을 내보내요. 그러면 스냅샷 식별자가 반환됩니다, 예:

BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT pg_export_snapshot();
 pg_export_snapshot
---------------------
 00000003-0000001B-1
(1 row)

그런 다음 새로 연 트랜잭션의 시작 부분에서 SET TRANSACTION SNAPSHOT 명령에 스냅샷 식별자를 주세요:

BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '00000003-0000001B-1';

호환성 (Compatibility)

이 명령들은 DEFERRABLE 트랜잭션 모드와 SET TRANSACTION SNAPSHOT 형태를 제외하면 SQL 표준에 정의되어 있어요. 그 둘은 PostgreSQL 확장 기능이에요.

SERIALIZABLE은 표준에서 기본 트랜잭션 격리 수준이에요. PostgreSQL에서는 보통 기본이 READ COMMITTED지만, 위에서 언급한 대로 바꿀 수 있어요.

SQL 표준에는 이 명령들로 설정할 수 있는 트랜잭션 특성이 하나 더 있어요: 바로 진단 영역(diagnostics area)의 크기예요. 이 개념은 임베디드 SQL에 특화된 것이므로 PostgreSQL 서버에서는 구현되지 않았어요.

SQL 표준은 연속된 transaction_modes 사이에 쉼표를 요구하지만, 역사적인 이유로 PostgreSQL은 쉼표 생략을 허용해요.

더 알아보기 (Learn more)