[PostgreSQL] 트랜잭션 격리(isolation) 수준
PostgreSQL이 SQL 표준을 잘 따르는 편이긴 하지만, 트랜잭션에 대해서는 그렇지 않은 것 같다.
SQL 표준
SQL 표준에 따르면 트랜잭션 격리 수준은 4가지가 있는데, 오른쪽으로 갈수록 제약이 느슨해진다.
Serialization > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED
Serialization은 가장 강한 제약이다. 트랜잭션이 절대로 동시에 실행되지 않고, 하나씩만 순서대로 실행된다.
때문에 성능저하가 심해질 수 있고, 대기열에 밀려서 처리가 되지 않을 수도 있어서 재시도 처리가 필요하다.
그래서 좀 극단적인 경우에 사용한다.
REPEATABLE_READ는 한 트랜잭션 내에서 여러번 SELECT를 해도 항상 똑같이 받아올 것임을 보장한다. 다만 외부에서 발생한 수정이 아닌, 현재 자신의 트랜잭션 내에서 발생한 수정은 반영된다.
READ_COMMITTED는 커밋된 것들만 읽을 수 있으며, 쿼리가 시작한 당시의 데이터만 참조 가능하다. 다만, 현재 트랜잭션에서 2번의 select가 있을 경우, 그 사이에 다른 트랜잭션이 커밋을 완료했다면 그 변경사항은 두번째 select에서 반영될 수 있다.
READ_UNCOMMITTED는 커밋되지 않은 내용까지도 읽어올 수 있다. 이를 dirty read라고 한다. 실제로는 거의 쓰이지 않는다.

PostgreSQL에서
기본값은 READ_COMMITTED이다.
그리고 READ_UNCOMMITTED는 위험성과 동시성 성능 저하를 이유로 구현되지 않아 사실상 READ_COMMITTED와 같다.
트랜잭션 레벨을 바꾸는 법은 대략 이렇다.
begin으로 블럭을 열어보면
기본설정은 read committed임을 볼 수 있다.
그걸 set transaction으로 바꿔주면 된다.
레벨에 넣을 수 있는 값은 SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED이다.
이래저래 작업하다가.. 원래 하던대로 commit으로 닫으면 끝이다.

참조
https://brownbears.tistory.com/272
https://www.postgresql.org/docs/current/transaction-iso.html