database
Database에서 트랜잭션(Transaction)이란 DB의 상태를 변화시키기 위한 일련의 작업 단위로 데이터베이스에서 여러 쿼리를 하나의 작업 단위로 묶어 처리하는 개념입니다. 이를 통해 원자성(Atomicity), 일관성(Consistency), 독립성(Isolation), 지속성(Durability)이라는 네 가지 핵심 특성을 확보할 수 있는데, 이를 흔히
이러한 트랜잭션을 다룰 때 대표적으로 사용하는 명령으로는 Commit과 Rollback이 있습니다. Commit은 트랜잭션 내 작업이 정상적으로 끝났을 때 변경 사항을 데이터베이스에 최종 반영하는 명령이며, Rollback은 트랜잭션 수행 도중 문제가 생겼을 때 작업 이전 상태로 되돌리는 역할을 합니다. 이를 통해 예상치 못한 오류나 충돌이 발생하더라도, 데이터 무결성을 지키고 안정적인 데이터베이스 운영이 가능해집니다.
데이터베이스에서 트랜잭션은 여러 개의 쿼리를 논리적으로 하나의 작업 단위로 묶어 처리합니다. 하지만 여러 트랜잭션이 동시다발적으로 실행되는 경우, 데이터를 어떻게 격리해야 안전하게 관리할 수 있을까요? 바로 이때 중요한 것이
트랜잭션들끼리 얼마나 고립되어있는지(잠금 수준)을 나타내는 것으로, 격리 수준은 크게 4가지로 표현됩니다.
Read Uncommitted는 “커밋되지 않은 데이터를 읽을 수 있게 하는” 가장 낮은 격리 수준을 의미합니다. 다른 트랜잭션에서 아직 커밋되지 않은, 즉 확정되지 않은 데이터를 읽을 수 있습니다. 이 말은 트랜잭션이 진행 도중에 롤백될 수도 있으므로, 일시적으로 볼 수 있었던 데이터가 실제 DB에 반영되지 않을 가능성이 있습니다. 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽을 수 있어서, “Dirty Read”가 발생합니다. 예를 들어, A 트랜잭션이 어떤 데이터를 수정했지만 커밋하기 전에 B 트랜잭션이 그 데이터를 읽어버린 뒤, A 트랜잭션이 롤백한다면 B 트랜잭션은 유효하지 않은 데이터를 읽은 셈이 됩니다.
Dirty Read가 발생할 수 있을 만큼 보안이나 무결성 면에서 가장 위험하지만, 동시에 가장 높은 동시성(속도)를 확보할 수 있는 수준입니다.
Committed Read는 “커밋된 데이터에만 접근하는” 격리 수준으로, Read Uncommitted보다 한 단계 더 엄격합니다. 다른 트랜잭션에서 변경한 값이라도, 이미 커밋된 데이터만 읽을 수 있습니다. 따라서 Dirty Read 문제는 해결됩니다. A 트랜잭션이 같은 SELECT 문을 두 번 실행했을 때, 그 사이에 B 트랜잭션이 데이터를 변경하고 커밋하면 A 트랜잭션이 얻는 결과가 달라질 수 있습니다. 이를 Non-Repeatable Read라고 부릅니다.
Dirty Read는 방지하지만, 동일한 SELECT 쿼리를 반복 실행했을 때 결과가 일관되지 않을 수 있어 반복된 읽기(Repeatable Read)가 보장되지 않습니다.
Repeatable Read는 “동일한 트랜잭션 내에서는 같은 데이터를 읽으면 항상 같은 결과가 반환되도록” 보장하는 격리 수준입니다. MySQL InnoDB 등 일부 DB 엔진에서는
Non-Repeatable Read까지 방지하지만, 일부 DB에서는 Phantom Read가 발생할 수 있습니다. 다만 MySQL InnoDB 등 특정 엔진에서는 Phantom Read도 대부분 방지합니다.
Serializable은 “모든 트랜잭션을 순차적으로 실행하는 것과 동일하게 보이도록” 하는 최상위 격리 수준입니다. 트랜잭션 간에 병행 실행이 거의 제한되어, 모든 부정합 문제(Dirty Read, Non-Repeatable Read, Phantom Read)를 완벽히 방지할 수 있습니다. 처리 과정을 직렬(순차)로 보장하기 때문에, 동시성 측면에서 성능 저하가 클 수 있습니다. 서로 트랜잭션이 동시에 접속하려고 하면 순차 처리 때문에 대기가 발생하거나, 동시에 Lock을 요청하여 데드락 상황이 생길 수 있습니다.
가장 안전하지만 가장 느린 수준이며, 실제 운영 환경에서는 성능 저하를 유의해야 합니다.
대부분의 데이터베이스에서는 기본적으로 Repeatable Read 또는 Committed Read를 채택해, 무결성과 성능 간의 합리적인 타협점을 도출합니다. 프로젝트 특성 및 데이터 중요도, 동시성 요구사항 등을 고려하여 적합한 격리 수준을 선택하는 것이 중요합니다.