[PostgreSQL] Isolation level에 따른 트랜잭션 처리 방법
Isolation level
소프트웨어를 개발하는 경우 데이터베이스 트랜잭션 내에서 복잡한 방식으로 데이터를 운영하는 코드에서 비즈니스 논리 오류가 발생하지 않도록 트랜잭션이 서로 어떻게 영향을 미치는지 알아야 합니다.
PostgreSQL에서 트랜잭션을 설정하는 방법은 총 4가지
1. READ UNCOMMITTED (낮은 격리수준)
설정에는 정의되어 있지만, 지원하지 않습니다.
(READ COMMITTED와 동일)
2. READ COMMITTED (기본값)
커밋된 데이터만 READ 할 수 있으며, DIRTY READ가 불가능.
(DIRTY READ : 다른 트랜잭션에서 커밋하지 않는 데이터를 읽을 수 있는 것)
3. REPEATABLE READ
조회 시 항상 동일한 데이터 응답을 보장.
4. SERIALIZABLE (높은 격리 수준)
모든 작업이 동시에 일어나지 않고 하나의 트랜잭션 처리처럼 동작합니다.
종류
테스트를 위해 order라는 테이블 객체 생성
create table "order"
(
id bigserial,
description varchar(255),
total double precision,
status varchar(255)
);
alter table "order"
owner to postgres;
Dirty Read
커밋되지 않은 다른 Transaction의 값들도 읽을 수 있다.
첫번째 Transaction이 어떤 record를 업데이트.
Read Commited
Non-Repeatable Reads
처음의 읽었던 결과값이랑 나중에 읽었던 결과값이 달라지는 현상. 다른 트랜잭션에서 업데이트 된 값이 바로 읽어짐.
Repeatable Read
non-repeatable read를 해결하기 위한 방법.
Postgresql이 두번째 읽을때 첫번째 읽은 결과값이 동일한 것을 보장해준다.
Serializable
아래 예시는 Lost updates에 대한 문제를 보여준다.
왼쪽에서 update 200으로 한 데이터가 다른한쪽에서 300으로 업데이트 하자 사라지게 된다.
첫번째 row가 update되자, 다른 transaction에서 해당 변경이 불가능하도록 막는다.
코드로 알아보기
현재 설정정보
현재 postgres의 설정되어있는 Transaction Isolation Level을 확인할 수 있다.
show transaction isolation level
설정으로 변경하기 (postgresql.conf 내 설정을 수정하는 방법)
#default_transaction_isolation = 'read committed'
데이터베이스의에 명령어로 Default 격리 수준 변경하기
ALTER DATABASE DBNAME SET DEDFAULT_TRANSACTION_ISOLATION TO 'REPEATABLE READ';
트랜잭션 격리 수준 변경하기 (질의)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
정리
격리수준은 데이터베이스 트랜잭션의 실행 동작을 제어하는 기능으로, 동시에 여러 Transaction을 다룰 때 발생하는 문제를 해결하는데 도움을 줍니다.
Isolation Level | 설명 | Dirty Read | Non-Repeatable Read | Phantom Read | 고립성(안정성) | 동시성 |
Read Uncommitted |
커밋되지 않은 데이터도 읽을 수 있다. | O | O | O | 낮다 | 높다 |
Read Commited | X | O | O | 중간 | 중간 | |
Repeatable Read |
하나의 트랜잭션에서는 하나의 스냅샷만 사용한다 | X | X | O | 중간 | 중간 |
Serializable | Read 시에 DML 작업이 동시에 진행될 수 없다. | X | X | X | 높다 | 낮다 |