이 글에선 트랜잭션의 격리 수준을 간단히 소개하고 PostgreSQL에서 사용하는 방법을 알아본다.
📌 격리수준의 종류
> READ UNCOMMITTED
트랜잭션의 변경사항을 Commit하지 않아도 다른 트랜잭션에서 읽어들일 수 있음
dirty read 현상이 발생할 수 있다. (완료되지 않은 데이터를 다른 트랜잭션에서 접근하는 것)
> READ COMMITTED (기본값)
트랜잭션은 Commit한 데이터만 읽어들임
non repeatable read 현상이 발생할 수 있다. (경우에 따라서 같은 읽기 명령이라도 결과가 다를 수 있음)
> REPEATABLE READ
트랜잭션이 항상 자신이 생성되기 전에 변경된 데이터만 읽어들임
Update Lock
phantom read 현상이 발생할 수 있다. (삭제/추가 잠금이 없기 때문에, 읽었던 데이터가 사라지거나 다른게 추가되는 상황이 나타날 수 있다.)
> SERIALIZABLE
동시성을 포기하고 안전성을 잡은 방법.
Update/Delete/Insert Lock
> SNAPSHOT
데이터를 모조리 복사해서 수정 후, 병합하는 방식 (병합 시 충돌 확인을 함.)
아래에 자세한 설명이 나와있다.
https://www.geeksforgeeks.org/what-is-snapshot-isolation/
더 자세한 내용은 아래 참고
- https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation
- https://www.postgresql.org/docs/current/sql-set-transaction.html
📌 PostgreSQL에서 격리수준을 설정하는 방법
쿼리는 다음과 같다.
SET TRANSACTION ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
실제로 동작하는건 3개로, READ UNCOMMITTED는 READ COMMITTED으로 대체된다.
SNAPSHOT은 좀 복잡하게 설정해야 한다.
아래와 같이 해야하는데, 스냅샷 id는 pg_export_snapshot()으로 구해야 한다.
SET TRANSACTION SNAPSHOT 스냅샷id
예제는 아래와 같다.
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT pg_export_snapshot();
pg_export_snapshot
---------------------
00000003-0000001B-1 -- 이게 SNAPSHOT id
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
SNAPSHOT을 사용할때, 트랜잭션 격리수준은 SERIALIZABLE이나 REPEATABLE READ를 써야 한다. (READ COMMITTED을 쓰면 하나의 명령어가 수행될 때마다 하나의 SNAPSHOT을 생성한다고 함)
'프로그래밍 > DB' 카테고리의 다른 글
N+1 쿼리 문제를 이해하고 해결하기 (번역) (비공개) (0) | 2022.11.14 |
---|---|
[PostgreSQL] Heap, Block, Tuple (0) | 2022.08.05 |