데이터베이스에서 하나의 작업 단위를 의미 → 모든 작업이 한꺼번에 수행되어야함
일련의 작업들이 모두 성공하거나, 모두 실패해야 하는 연산 집합 → 모든 작업이 성공해야 반영되고, 문제가 생기면 이전 상태로 돌아감. 즉, 중간 작업까지만 반영을 하는게 아니라 모든 작업을 원상태로 복구하는 것임
예시)
A 계좌 → B 계좌로 100만 원 송금 시:
1. 원자성 (Atomicity)
데이터베이스에 모두 반영되거나, 모두 반영되지 않아야 한다는 것
→ 하나의 작업이라도 실패하면 모든 변경사항 취소하고 롤백해야함
2. 일관성 (Consistency)
작업 처리 결과가 항상 일관성이 있어야 한다는 것
→ 트랜잭션이 진행되는 동안, DB 변경이 있더라도 처음에 참조하고 있던 DB로 읽음
3. 독립성 (Isolation)
동시에 여러 트랜잭션이 실행되더라도, 각 트랜잭션은 독립적으로 수행해야함
→ 하나의 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없음
4. 영구성 (Durability)
트랜잭션 완료 후 시스템 장애나 오류가 생겨도 결과가 영구적으로 보존하고 반영되어야 한다는 것
여러 트랜잭션이 동시에 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 여부 결정
가장 엄격한 격리 수준 상태
모든 트랜잭션을 순차적으로 실행한 것처럼 동작함
읽기, 쓰기, 추가에 대해 모두 잠금을 걸어 여러 트랜잭션이 동일한 레코드에 동시접근 불가능함 → 성능 떨어짐 → 그래서 극단적으로 보안이 중요한 경우에만 써야함
데이터 무결성과 일관성 완벽 보장
하나의 트랜잭션 내에 동일한 데이터를 여러 번 조회해도 동일한 결과 반환
MVCC(다중 버전 동시성 제어)를 사용해서 변경 전 데이터를 Undo 영역에 저장해 변경 전후 데이터 관리
트랜잭션 번호를 참조해 커밋된 시점의 데이터 사용
새로운 레코드가 추가되는 것은 막을 수 없음 (유령 읽기) → 근데 MySQL은 갭락을 사용해서 가능함.
MVCC를 통해 한 트랜잭션 내에서 동일한 결과를 보장하지만, 새로운 레코드가 추가되는 경우에는 부정합이 일어날 수 있음.

위의 예제를 보면 확인가능한데, B 트랜잭션이 먼저 실행되고 난 후 A 트랜잭션이 민규를 망규로 변경했음. 하지만 REPEATABLE READ는 트랜잭션 번호를 참고하여 먼저 실행된 트랜잭션 데이터만을 조회하는데 B 보다 나중에 실행된 트랜잭션 데이터가 존재하기 때문에 언두 로그를 참고해서 데이터를 조회하게 됨. 이렇게 일관성을 지키며 동일한 결과를 확인할 수 있음.
하지만 새로운 레코드의 추가는 막을 수가 없음. → 유령 읽기 ⇒ 하지만 MVCC에 의해 일반적인 상황에서는 유령 읽기가 발생하지 않음. 나중에 트랜잭션이 추가한 레코드는 무시하기 때문임.
그렇다면 어떤 상황에 유령 읽기가 발생하냐?
잠금이 사용되는 경우.
B 사용자가 “SELECT FOR UPDATE = 쓰기 잠금” 로 조회를 한다.
MySQL은 갭락을 사용해서 유령읽기 막음
나머지는안막아줌 postgres같은거
갭락 → 예를 들면 50 이상에 락을 건다. 그럼 트랜잭션 종료 이전까지 쭉 락을 거는거임. 현재 테이블에서 50까지 있는데 A에서51 추가한다고 해도 락이 걸려있어서 추가 못하는 느낌
갭락 없으면 그냥 50이상에 락 거는거 현재 테이블 기준으로 걸어서 이 다음 A가 51 추가할려고 하면 추가하고 커밋됨. 그리고 B가 또 읽으면 유령읽기가 되는거임
커밋된 데이터만 조회할 수 있음 → 하나의 트랜잭션 내에서 동일한 쿼리 반복하면 다른 트랜잭션의 커밋된 결과를 읽게 됨
더티 리드 방지 가능, 동시성 처리 성능 높음
유령읽기(Phantom Read): 새롭게 추가되거나 삭제되는거 갭락으로 막기
반복읽기불가능(Non-Repeatable Read) : 수정되는거? 레코드락으로 막기
더티 리드: 한 트랜잭션에서 커밋되지 않은 변경된 데이터를 다른 트랜잭션이 읽을 수 있는 상황 즉, 아직 확정되지 않은 데이터를 읽어와 작업을 수행함으로써 잘못된 데이터를 참조하거나 잘못된 연산 결과가 발생할 수 있음
커밋되지 않은 데이터도 조회할 수 있음 → 다른 트랜잭션에서 커밋되지 않은 데이터 읽을 수 있음 ⇒ 더티 리드 발생할 수 있음
격리 수준이 낮기 때문에 트랜잭션 간 충돌이 거의 없고 빠르게 처리됨
무결성과 일관성 보장이 약함
로그 저장같은 단순 작업에 사용됨
데이터 변경 작업 전에 변경 전 데이터를 저장하는 공간
ROLLBACK 상황에 Undo 영역을 참조하여 변경 전 상태로 복구 혹은 MVCC 제공
데이터 변경 작업의 변경 후 데이터를 저장하는 공간
COMMIT 되기 전 변경된 데이터를 로그 파일에 기록, 시스템 장애가 발생하더라고 복구할 수 있도록 보장
느낀점
DB는 너무 재미있고 공부할 때마다 좋은데... 설명하기 너무 어렵다.
이 글을 읽으면 이해할 사람이 있을까? 싶은데 나중에 시간이 지난 뒤 읽어보고 이상하다 싶으면 수정해야겠다. 트랜잭션 격리 수준은 참고 자료의 블로그 추천. 계속 읽다보면 이해가 됨. 예제 사진도 있어서 좋음.
그리고 InnoDB의 갭락이라던가 격리수준이 어떤지 몰랐는데 알게 돼서 좋았다
참고 자료
[MYSQL] 📚 트랜잭션(Transaction) 개념 & 사용 💯 완벽 정리
[MySQL] 트랜잭션의 격리 수준(Isolation Level)에 대해 쉽고 완벽하게 이해하기