여러 트랜잭션이 동시에 실행될 때 특정 트랜잭션이 다른 트랜잭션의 데이터를 볼 수 있도록 허용할지 여부를 결정하는 수준을 의미합니다.
즉, A 트랜잭션이 실행되는 도중에 B 트랜잭션에서 데이터를 수정하거나 조회하는 경우, A가 이 변경된 데이터를 읽을 수 있도록 허용할 것인지, 아니면 차단할 것인지에 따라 격리 수준이 달라집니다.
트랜잭션은 ACID (Atomicity, Consistency, Isolation, Durability) 원칙을 따라야 합니다.
이 중에서 Isolation(고립성) 은 트랜잭션이 서로 독립적으로 실행되도록 보장하는 개념입니다.
그러나 모든 트랜잭션을 완전히 고립시키면 동시 처리 성능이 크게 저하될 수 있습니다.
그래서 현실적으로는 데이터 정합성과 성능의 균형을 맞추기 위해 격리 수준을 설정하게 됩니다.
격리 수준이 높아질수록 데이터 정합성(일관성)이 보장되지만, 동시 처리 성능은 떨어집니다.
• 가장 낮은 격리 수준
• 트랜잭션이 커밋되지 않아도 다른 트랜잭션이 데이터를 읽을 수 있음
• 락을 거의 사용하지 않기 때문에 성능은 가장 좋지만, 데이터 정합성 문제 발생 가능성도 가장 높음
⚠️ 발생할 수 있는 문제
• Dirty Read
• 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽어버리는 현상
• 예를 들어, 트랜잭션 A가 사용자 잔액을 100에서 50으로 변경했는데, 아직 커밋되지 않은 상태에서 트랜잭션 B가 이 데이터를 읽어버림
• 만약 A가 롤백하면 B가 읽은 데이터는 실제 데이터와 다르게 됨
✅ 언제 사용?
• 데이터 정합성이 중요하지 않은 환경 (ex. 로그 기록, 통계 데이터 처리 등)
• 커밋된 데이터만 읽을 수 있음
• 다른 트랜잭션이 데이터를 변경하더라도, 커밋되기 전에는 볼 수 없음
• Dirty Read는 방지되지만, Non-Repeatable Read 문제는 발생할 수 있음
⚠️ 발생할 수 있는 문제
• Non-Repeatable Read
• 동일한 데이터를 두 번 조회할 때, 첫 번째 조회 시점과 두 번째 조회 시점의 데이터가 다를 수 있음
• 예를 들어, A 트랜잭션이 특정 고객의 잔액을 조회했을 때 100원이었지만, B 트랜잭션이 이 값을 50원으로 변경하고 커밋한 후, A가 다시 조회하면 50원이 됨
✅ 언제 사용?
• 대부분의 RDBMS의 기본값
• 데이터 정합성은 중요하지만, 성능도 고려해야 하는 일반적인 경우 (ex. 은행 시스템, 전자상거래)
• 트랜잭션이 시작된 시점의 데이터를 계속 유지
• 즉, 한 트랜잭션 내에서 동일한 데이터를 여러 번 조회해도 값이 변하지 않음
• Non-Repeatable Read 문제를 해결하지만, Phantom Read 문제는 발생할 수 있음
⚠️ 발생할 수 있는 문제
• Phantom Read
• 같은 조건으로 조회했을 때, 첫 번째 조회에는 없던 데이터가 두 번째 조회에서는 나타나는 문제
• 예를 들어, 트랜잭션 A가 SELECT * FROM users WHERE age > 20 을 수행했을 때, 처음에는 10명의 데이터가 나왔지만, 트랜잭션 B가 새로운 사용자를 추가하고 커밋하면, A가 같은 쿼리를 실행했을 때 11명이 나올 수 있음
✅ 언제 사용?
• 데이터 정합성이 중요한 서비스 (ex. 은행, 금융 거래)
• 가장 엄격한 격리 수준
• 트랜잭션이 완료될 때까지 다른 트랜잭션이 동일한 데이터에 접근 불가능
• Phantom Read 문제까지 완벽하게 방지하지만, 성능이 크게 저하됨
⚠️ 단점
• 성능 저하
• 트랜잭션이 순차적으로 실행되어 동시 처리가 어려움
• 데드락(Deadlock) 발생 가능성 증가
✅ 언제 사용?
• 데이터 정합성이 최우선인 경우 (ex. 금융 결제 시스템, 항공 예약 시스템)
데이터 정합성(Data Integrity) 이란, 데이터가 일관되고 정확하며, 신뢰할 수 있는 상태를 유지하는 것을 의미합니다.
즉, 데이터가 손상되거나 오류가 발생하지 않도록 보장하는 개념입니다.
1. 일관성 유지
• 같은 데이터를 여러 번 조회해도 항상 같은 값이 나와야 함
• 예를 들어, 은행 계좌의 잔액이 갑자기 변하지 않아야 함
2. 데이터 오류 방지
• 트랜잭션이 실행되다가 실패했을 경우, 잘못된 데이터가 저장되지 않도록 보호해야 함
• 예를 들어, 상품을 구매했는데 결제는 되었지만 주문 정보가 사라지는 문제 방지
3. 보안 및 신뢰성 확보
• 시스템 내 데이터가 변조되지 않고, 정확한 데이터만 유지되도록 보장
• 특히, 금융, 의료, 전자상거래 등 중요한 시스템에서는 필수
1️⃣ Dirty Read (더러운 읽기)
• 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 문제
• 예를 들어, A 트랜잭션이 계좌 잔액을 100에서 50으로 수정했지만 아직 커밋되지 않았을 때,
B 트랜잭션이 이 값을 읽어버리면 A가 롤백할 경우 B는 잘못된 데이터를 사용하게 됨
• 해결 방법: Read Committed 이상 격리 수준 사용
2️⃣ Non-Repeatable Read (반복 불가능한 읽기)
• 같은 데이터를 여러 번 조회했을 때 값이 다르게 나오는 문제
• 예를 들어, A 트랜잭션이 한 사용자의 잔액을 조회했을 때 100원이었는데,
B 트랜잭션이 50원으로 변경하고 커밋한 후, A가 다시 조회하면 50원이 나오는 문제
• 해결 방법: Repeatable Read 이상 격리 수준 사용
3️⃣ Phantom Read (유령 읽기)
• 같은 조건으로 조회했을 때, 첫 번째 조회에는 없던 데이터가 두 번째 조회에서는 나타나는 문제
• 예를 들어, A 트랜잭션이 SELECT * FROM orders WHERE status='PENDING' 를 실행했을 때,
B 트랜잭션이 새로운 주문을 추가하고 커밋한 후, A가 다시 같은 쿼리를 실행하면 결과가 달라짐
• 해결 방법: Serializable 격리 수준 사용
트랜잭션 격리 수준은 데이터 정합성과 성능 사이에서 균형을 맞추기 위한 설정입니다.
• 데이터 정합성이 중요하면 Repeatable Read 이상
• 성능이 중요하면 Read Committed 이하
• Serializable은 데이터 정합성을 가장 잘 보장하지만, 성능이 가장 낮음
📌 일반적으로 Read Committed가 가장 많이 사용되며, Repeatable Read는 데이터 정합성이 중요한 경우 선택됩니다.
📌 데이터 정합성을 보장하려면?
✔️ 트랜잭션 격리 수준 설정 (Read Committed 이상)
✔️ 데이터베이스 제약 조건 활용 (PK, FK, CHECK 등)
✔️ 트랜잭션 실패 시 롤백(Rollback) 적용
✔️ 정규화된 데이터 모델 설계