본문으로 바로가기

트랜잭션 격리 수준 (Isolation level)

category n년차 개발자 2022. 8. 20. 02:21
반응형

트렌젝션 (Transaction)

데이터베이스의 상태를 변경시키기 위해 수행하는 작업 단위

논리적인 작업 셋 자체가 100% 적용되거나 (COMMIT) 또는 아무것도 적용되지 않아야 함(ROLLBACK)을 보장해주는 것입니다.

 

COMMIT

하나의 트렌잭션이 성공적으로 끝나서 데이터베이스가 일관성 있는 상태에 있음을 의미

 

ROLLBACK

트렌잭션이 원자성이 깨질 떄, 즉 하나의 트랜잭션 처리가 비정상적으로 종료 되었을 때의 상태를 의미

 

특징

  • 원자성 (Atomicity)
    • 트렌잭션이 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다.
  • 일관성 (Consistency)
    • 트렌잭션이 작업 처리 결과가 항상 일관되어야 한다.
  • 독립성 (Isolation, 격리성)
    • 하나의 트렌잭션은 다른 트랜잭션에 끼어들 수 없고 마찬가지로 독립적임을 의미한다.
    • 각각의 트렌잭션은 독립적이라 서로 간섭이 불가능하다.
  • 지속성 (Durability)
    • 트랜젝션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 한다.

 

트랜젝션은 원자성, 일관성, 지속성을 보장하는데 문제는 격리성입니다.

트랜젝션간에 격리성을 완벽히 보장하려면 동시에 처리되는 트랜잭션을 거의 차례대로 실행을 해야 합니다.

하지만 이렇게 처리를 하면 성능이 매우 나빠지게 됩니다.

이러한 문제로 인해 ANSI 표준은 트랜젝션의 격리 수준을 4단계로 나누어 정의하고 있습니다.

트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것

 

docker mysql

 

# docker run
docker run --name=mysql-container -e MYSQL_ROOT_PASSWORD=<password> -d -p 3306:3306 mysql:latest

# mysql container conn
docker exec -it mysql-container bash

# mysql conn
mysql -uroot -p

# mysql db conn
use mysql

 

트랜잭션 격리 수준 확인

mysql> SHOW VARIABLES LIKE '%isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

 

 

  • 레벨 0단계 READ UNCOMMITTED
    • 트랜젝션에 처리중이거나, 아직 Commit 되지 않은 데이터를 다른트랜젝션에 읽는 것을 허용함.
데이터: 1번지역 서울
1. A 트랜젝션 BEGIN
2. B 트랜젝션 BEGIN
3. B 트랜젝션 1번 지역 서울에서 부산 UPDATE
4. A 트랜젝션 1번 지역 조회 -> 부산
5. A 트랜젝션 COMMIT
6. B 트랜젝션 COMMIT
  • 레벨 1단계 READ COMMITTED
    • 트랜젝션에서 Commit 완료된 데이터만 다른 트랜젝션에 허용함.
    • 같은 A트랜젝션 안에서 동일한 SELECT 문을 수행했을 때 다른 결과값이 나올 수 있음.
데이터: 1번지역 서울
1. A 트랜젝션 BEGIN
2. B 트랜젝션 BEGIN
3. B 트랜젝션 1번 지역 서울에서 부산 UPDATE
4. A 트랜젝션 1번 지역 조회 -> 서울
5. B 트랜젝션 COMMIT
6. A 트랜젝션 1번 지역 조회 -> 부산
7. A 트랜젝션 COMMIT
  • 레벨 2단계 REPETABLE READ
    • 트랜젝션에서 Commit 완료된 데이터만 다른 트랜젝션에 허용함.
    • 같은 A트랜젝션 안에서 동일한 SELECT 문을 수행했을 때 항상 같은 결과값이 나옴.
데이터: 1번지역 서울
1. A 트랜젝션 BEGIN
2. B 트랜젝션 BEGIN
3. B 트랜젝션 1번 지역 서울에서 부산 UPDATE
4. A 트랜젝션 1번 지역 조회 -> 서울
5. B 트랜젝션 COMMIT
6. A 트랜젝션 1번 지역 조회 -> 서울
7. A 트랜젝션 COMMIT
  • 레벨 3단계 SERIALIZABLE
    • 트랜젝션이 완료될 떄까지 SELECT 문이 사용되는 모든 데이터에 Shared Lock이 걸림
데이터: 1번지역 서울
1. A 트랜젝션 BEGIN
2. A 트랜젝션 1번 지역 조회 (shared lock)
3. B 트랜잭션 접근 X

 

 

부정합 문제

 

Dirty Read

- 레벨 0단계 Read Uncommitted 발생

- 어떤 트랜잭션에서 아직 실행이 끝나지 않은 다른 트랜잭션에 의한 변경사항을 보게되는 문제
- 커밋되지 않은 수정중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생하는 현상

Non-Repeatable Read

- 레벨 0단계 Read Uncommitted 발생
- 레벨 1단계 Read Committed 발생

- 한 트랜잭션에서 동일한 SELECT 쿼리를  두 번 수행할 때, 그 사이에 다른 트랜잭션이 값을 수정 or 삭제하면서 동일한 트랜잭션에서 실행된 두 쿼리의 결과가 다르게 나타나는 일관성이 깨지는 문제
- 한 트랜잭션에서 똑같은 SELECT를 수행했을 때 항상 같은 결과를 반환해야 한다는 Repeatable Read 정합성이 깨짐

Phantom Read

- 레벨 0단계 Read Uncommitted 발생
- 레벨 1단계 Read Committed 발생
- 레벨 2단계 Repeatable Read 발생

- 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽었을 때, 첫번째 쿼리에서는 없던 레코드가 두번째 쿼리에서 나타나는 문제- 트랜잭션 중 새로운 레코드 삽입을 허용하기 때문에 발생

 

참고

반응형