TIL / the transaction isolation level

flobeeee·2022년 3월 15일
1

Today I Learned

목록 보기
24/35

☀️ 개요

adonisJS / transaction 사용하기 ( + 에러상황 4가지 해결)
지난 포스팅 4번째 에러와 연관이 되는 글이다.
transaction 과정 중에 임시저장된 데이터(commit 전)를 가져와서 그 다음 데이터가 반영이 되길 원했는데,
실제로는 실제 DB에 반영된 데이터를 가져와서 작업이 진행됐다.
나는 이 부분이 단순한 에러라고 치부했는데, 확인해보니 저 현상에 대한 transaction options이 있었다.

AdonisJS/transaction 공식문서에서 해당 옵션을 찾을 수 있었다.


/**
* Same as knex. Need to redefine, as knex doesn't export this
* type
*/
export type IsolationLevels = 'read uncommitted' | 'read committed' | 'snapshot' | 'repeatable read' | 'serializable';

테스트를 했는데, 잘 작동이 되지 않아서 확인해보니 위 주석을 발견했다.
현재 adonisJS에서는 사용할 수 없어 보인다.

이왕 이렇게 된거 옵션에 대해서 공부해봤다.


☀️ transaction isolation

트랜잭션이란 데이터베이스에서 데이터에 대한 하나의 논리적 수행단계이다.
데이터베이스 트랜잭션이 안정적으로 수행한다는 것을 보장하기 위한 ACID 성질이 있다.

원자성(Atomicity) : 트랜잭션 내에서 일어나는 작업은 하나로 본다.(모두 성공하거나 모두 실패)
일관성(Consistency) : 일관성있는 데이터베이스를 유지해야 한다.
트랜잭션이 실행되기 전의 데이터베이스 내용이 잘못 되어 있지 않다면 트랜잭션이 실행된 이후에도 데이터베이스의 내용에 잘못이 있으면 안된다.
고립성(Isolation) : 다른 트랜잭션이 작업에 못끼어들게 해야 한다. 이 부분은 제어가 가능하다.
지속성(Durability) : 성공한 트랜잭션의 데이터가 저장이 되어야 한다.
트랜잭션이 성공적으로 수행되면 그 트랜잭션이 갱신한 데이터베이스의 내용은 영구적으로 저장된다.

이 중에 고립성에 대한 옵션이 이 글의 주제이다.


☀️ 1. read uncommitted

한 트랜잭션 내에서 임시저장된 데이터, 즉 commit 전 데이터에 다른 트랜잭션 접근이 가능하다.

rollback이 일어나면 해당 데이터는 없던 데이터가 되는거라서 잘못된 데이터를 읽을 우려가 있다. (drity read)

권장하지 않는 옵션이라고 한다.

☀️ 2. read committed

트랜잭션은 커밋한 데이터만 읽는다.

커밋 전의 데이터를 읽고, 다른 트랜잭션이 작업을 끝낸 후, 다시 읽으면 데이터가 달라진다.

하나의 트랜잭션 내에서 같은 SELECT 문을 날려도 결과가 다를 수 있다.

☀️ 3. snapshot (only mssql)

트랜잭션 수행 이전 버전의 데이터를 읽는다.

한 데이터에 대해 두 가지의 트랜잭션이 일어나면 먼저 commit 된 내역이 반영된다.

☀️ 4. repeatable read (mysql 기본 격리수준)

하나의 트랜잭션은 하나의 스냅샷만 사용한다.

트랜잭션 시작 전에 데이터를 확인한 후, 해당 트랜잭션이 끝날 때까지 같은 데이터를 본다.

다른 트랜잭션에서 해당 데이터에 commit을 해도 바뀌지 않는다. (실제데이터는 바뀜)

☀️ 5. serializable

가장 엄격한 수준이다.

트랜잭션을 순차적으로 진행시킨다. 성능저하 우려가 있다.


[참고자료]

위키백과/ACID
Spring @Transactional 옵션
[Sql Server/MSSQL] 트랜잭션 격리 수준
[MySQL] isolation level 종류 및 특징

profile
기록하는 백엔드 개발자

0개의 댓글