# Transaction과 Isolation Level

 

Transaction(트랜잭션)이란? 논리적인 작업의 최소 단위이다.

트랜잭션이 왜 필요할까?

하나의 작업이 있는데 여러번 연산을 해야하는 상황이 있다.

예를 들어, 친구에게 계좌이체를 한다고 해보자.

계좌이체라는 하나의 작업은 2가지 연산으로 구성된다.

1. 내 계좌에서 돈을 출금하는 UPDATE하는 연산

2. 친구 계좌에 돈을 입금하는 UPDATE하는 연산

 

만약 1번 작업은 수행됐는데 2번 작업에서 에러가 나면

내 계좌에서 돈이 빠져나갔는데

친구는 돈을 못받은 상황이 되는 것이다.

 

즉, 트랜잭션은 하나의 작업을 수행하는데

여러 개의 연산을 하나로 묶어서

전부 실행되야지 일부만 실행되면 안된다. "All or Nothing - 원자성"

트랜잭션이 성공적으로 수행이 되면

내 계좌에서 빠져나간 돈만큼의 돈이

친구 계좌에 들어온다. 즉, 일관성을 만족해야 하는 것이다.

 

내가 돈을 송금하는 동안 다른 친구도 그 친구에게 돈을 송금할 수 있다.

계좌이체 트랜잭션이 동시에 들어오는 경우

다른 트랜잭션이 영향을 줄 수 없게

트랜잭션의 격리성이 보장되야 한다.

 

트랜잭션이 반영된 후에도 시스템 장애가 발생하더라도

트랜잭션 작업 결과는 손실되지 않고 영구적으로 반영되야한다.

이를 지속성이라 한다.

 

정리하자면
트랜잭션은 ACID라는 4가지 특성을 만족해야 한다.
(Atomicity-원자성, Consistency-일관성, Isolation-격리성, Durability-지속성)

이 중에서 Isolation에 대해 더

자세히 알아보려고 한다.

DB에는 Isolation Level(트랜잭션 격리 수준)이라는 게 있다.

이는 하나의 트랜잭션이 조회 또는 변경 작업 중인데

다른 트랜잭션이 들어온 경우

어느 수준까지 데이터를 조회를 허용할지에 대해서 설정하는 것이다.

 

SQL 표준 Transaction Isolation Level에는 4가지가 있다.

1. Read Uncommitted

2. Read Committed

3. Repeatable Read

4. Serializable

 

1. Read Uncommitted는 커밋되지 않은 데이터도 읽을 수 있는 수준이다.

Select를 수행하는 경우 트랜잭션이 COMMIT 되지 않은 데이터를 읽을 수 있다(dirty read)

업데이트되지 않은 데이터를 읽는 것은 무결성을 깨뜨릴 위험성이 높다.

하지만 동시성이 향상되는 효과가 있기도 하다.

Oracle, PostgreSQL에서는 지원하지 않는다.

commit되지 않은 내용이 읽힌다.

 

2. Read Committed는 커밋된 데이터만 읽을 수 있다.

Select문은 이전에 커밋된 데이터만 읽을 수 있고

Write 작업은 해당 트랜잭션이 끝날 때까지 waiting하게 된다.

트랜잭션에서 select가 여러번 있을때, 다른 트랜잭션에서 커밋을 하면

커밋 후의 select는 커밋된 데이터를 참조하게 된다.(non-repeatable read)

 

3. Repeatable Read는 트랜잭션 시작 시점 데이터만 읽을 수 있다.

동일 데이터 Write 작업은 Read Committed처럼 Waiting이 되고

이미 트랜잭션이 시작됐는데 다른 트랜잭션에서 데이터가 변경된 경우

해당 데이터를 Select할 때 변경이전의 트랜잭션 시작 지점의 데이터를 읽게 된다.

select for update는 커밋된 데이터를 읽게 된다.

 

4. Serializable은 모든 읽기 작업은 shared lock을 가진다.

즉, 다른 트랜잭션은 해당 데이터를 변경하지 못한다.

 

만약 트랜잭션마다 consistency level이 다르면 어떻게 동작할까?

각 트랜잭션 특성을 생각하면 된다.

Repeatable Read 트랜잭션과 Serializable 트랜잭션이 있다고 가정하면

Serializable은 기본적으로 select만으로도 shared lock이 걸리므로

Repeatable Read 트랜잭션은 해당 데이터를 읽을 수 없다.

 

DB는 동시에 여러 client가 사용하게 되므로

성능면에서 동시성이 중요하고

데이터를 생각한다면 안정성이 중요하다.

그러나 이 두개를 모두 만족할 수는 없다.

서비스의 특성을 잘 파악하고

최적의 isolation level를 선택해서 잘 활용해야 할 것이다.

 

참고로 테스트는 MariaDB 10.2.11버전을 사용하였다.

 

[참고문서]
데이터베이스 개론(김연희 지음)
jupiny.com/2018/11/30/mysql-transaction-isolation-levels/
hyunki1019.tistory.com/111
blogs.oracle.com/oraclemagazine/on-transaction-isolation-levels
effectivesquid.tistory.com/entry/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-Isolation-Level

To be continued.........

 

 

Made by 꿩

'Database > RDBMS' 카테고리의 다른 글

[MySQL/MariaDB] my.cnf 메모리 설정  (0) 2022.06.11
[PostgreSQL] Architecture  (0) 2022.03.01
[MariaDB] mariabackup 백업 & 복구  (0) 2022.02.15
[MySQL/MariaDB] 계정 정보 추출  (0) 2021.11.11
MVCC 동시성 제어  (0) 2021.02.06

+ Recent posts