442. 일관성 (Consistency)과 무결성 보장

⚠️ 이 문서는 트랜잭션의 4대 특성(ACID) 중 두 번째 글자인 C(일관성)에 대한 내용으로, "작업 전에도 완벽해야 하고, 작업 후에도 완벽해야 한다"는 원칙하에 데이터베이스에 정의된 모든 규칙(무결성 제약 조건)을 철저하게 지켜내는 기술을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 데이터베이스에는 여러 가지 규칙(예: "잔고는 마이너스가 될 수 없다", "학번은 Null일 수 없다")이 있다. 트랜잭션은 이 규칙들을 절대로 깨뜨려서는 안 된다.
  2. 위반 상황: 내 통장에 1만 원이 있는데, 친구에게 5만 원을 이체하려고 했다. 이체가 성공해서 내 통장이 -4만 원이 되어버린다면 일관성이 깨진 것이다.
  3. 보장 기법: 데이터베이스 엔진은 트랜잭션이 수행될 때마다 무결성 제약조건(Integrity Constraints) 검사를 실행하며, 하나라도 위반하면 그 트랜잭션을 강제로 취소(Rollback)해 버린다.

Ⅰ. 개요: 룰은 절대적이다 (Context & Necessity)

우리가 게임을 할 때 "체력이 0 이하로 떨어질 수 없다"는 룰이 있다. 만약 독약 아이템을 먹어서 체력이 -10이 되어버린다면 게임에 심각한 버그(일관성 파괴)가 생긴 것이다.

데이터베이스도 마찬가지다. 개발자가 테이블을 만들 때 CHECK (잔액 >= 0) 이라는 무결성 제약 조건을 걸어두었다 치자.

  • 사용자가 5만 원을 빼달라고 UPDATE 쿼리를 날렸다 (트랜잭션 시작).
  • DB가 계산을 해보니 잔액이 -4만 원이 될 판이다.
  • DB는 즉시 "안 돼! 일관성(Consistency)이 깨져! 돌아가!" 라며 트랜잭션을 거부하고 ROLLBACK 시켜버린다.

이처럼 트랜잭션이 수행되기 전과 수행된 후, 언제나 데이터베이스의 **'모순 없는 논리적 상태'**가 유지되는 것을 일관성이라고 부른다.

📢 섹션 요약 비유: 일관성은 **'학교의 교칙'**과 같습니다. "복장 불량 금지"라는 교칙(제약조건)이 있다면, 학교에 오기 전(트랜잭션 시작 전)에도 단정해야 하고, 하교할 때(트랜잭션 끝난 후)도 단정해야 합니다. 옷을 찢어버리려는 행동(잘못된 쿼리)은 선생님(DB 엔진)이 그 즉시 막아 세웁니다.


Ⅱ. 일관성을 지키는 무기들: 무결성 제약조건 ★

DB 엔진은 트랜잭션을 감시하기 위해 다음과 같은 깐깐한 문지기들을 세워둔다.

1. 개체 무결성 (Entity Integrity - 405번 문서)

  • "기본 키(PK)는 비어있거나 중복될 수 없다."
  • 만약 트랜잭션이 중복된 ID를 INSERT 하려고 하면, 즉시 일관성이 깨졌다고 판단하고 롤백시킨다.

2. 참조 무결성 (Referential Integrity - 406번 문서)

  • "자식 데이터는 부모 데이터에 존재하는 값만 가리킬 수 있다."
  • 만약 부모(부서) 데이터를 DELETE 하려고 하는데 자식(직원)이 남아있다면, 일관성을 지키기 위해 삭제 트랜잭션을 튕겨낸다.

3. 도메인 및 사용자 정의 무결성 (Domain / User-defined)

  • NOT NULL, CHECK (age > 0) 같은 개발자가 정해둔 규칙들이다.
  • 나이에 -5살을 넣으려는 쿼리가 들어오면 바로 차단당한다.

Ⅲ. 트랜잭션 도중의 '일시적 불일치' 허용

일관성에서 가장 오해하기 쉬운 부분이다. "트랜잭션이 '진행 중'일 때는 아주 잠깐 일관성이 깨져도 봐준다."

  • 내 잔고(1만 원), 친구 잔고(1만 원) $\rightarrow$ 전체 총합은 2만 원 (규칙)
  • 내가 친구에게 1만 원 이체 시작!
    1. 내 돈 차감: 내 잔고(0원). 친구 잔고(1만 원) $\rightarrow$ 총합이 1만 원으로 깨짐! (일시적 불일치)
    1. 친구 돈 증가: 내 잔고(0원). 친구 잔고(2만 원) $\rightarrow$ 총합 다시 2만 원 (일관성 회복!)
    1. COMMIT 완료.

이처럼 트랜잭션의 시작과 끝점에서는 완벽한 일관성을 지켜야 하지만, 괄호 안에서 이뤄지는 중간 과정에서는 잠깐 규칙이 어긋나는 것을 시스템이 눈감아준다. (물론 이 엉망인 중간 과정은 고립성(Isolation) 규칙 덕분에 남들에게 절대 보이지 않는다.)

┌──────────────────────────────────────────────────────────────┐
│           일관성(Consistency) 유지와 일시적 불일치 시각화              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ [ ⏱️ T1 시작 전 ] ──▶ (내 돈 1만 + 친구 1만 = 총합 2만 원) 🟢 정상    │
│                                                              │
│ ┌── 트랜잭션 진행 중 ────────────────────────────────────────┐ │
│ │ 1. 내 돈 빼기   ──▶ (내 돈 0원 + 친구 1만 = 총합 1만 원) 💥 룰 깨짐 │
│ │                  (남들에게는 이 상태가 안 보임 - 고립성)           │
│ │                                                          │ │
│ │ 2. 친구 돈 더하기 ──▶ (내 돈 0원 + 친구 2만 = 총합 2만 원) 🟢 복구  │
│ └──────────────────────────────────────────────────────────┘ │
│                                                              │
│ [ ⏱️ T1 완료 후 ] ──▶ (내 돈 0원 + 친구 2만 = 총합 2만 원) 🟢 정상    │
│                                                              │
│ ★ 결론: 중간에 잠깐 룰이 깨지더라도, 문 열고 나올 때(Commit) 완벽하면 된다.│
└──────────────────────────────────────────────────────────────┘

Ⅳ. 결론

"규칙 없는 데이터베이스는 그냥 엑셀 파일일 뿐이다." 일관성(Consistency)은 데이터베이스가 '데이터 쓰레기장'이 되지 않도록 지켜주는 근원적인 힘이다. 개발자는 애플리케이션(Java, Python) 코드에서 if (잔액 < 0) return error; 처럼 로직을 짜기도 하지만, 가장 완벽한 방어는 데이터베이스 테이블 스키마에 CHECKFK 같은 무결성 제약조건을 물리적으로 박아버리는 것이다. 코드는 버그를 낼 수 있어도, 데이터베이스 엔진이 강제하는 일관성 제약은 절대 뚫리지 않기 때문이다.


📌 관련 개념 맵

  • 관련 특성: 원자성(A), 고립성(I), 영속성(D) (440번 문서)
  • 보장 기법: Integrity Constraints (무결성 제약조건), Trigger (트리거)
  • 주의점: 분산 시스템의 CAP 이론에서 말하는 일관성(모든 노드가 동일한 데이터를 보는 것)과는 미묘하게 다른 뜻(데이터의 규칙 준수 여부)으로 쓰인다.

👶 어린이를 위한 3줄 비유 설명

  1. 엄마가 "통장에 있는 돈보다 더 큰 장난감은 살 수 없어!"라고 규칙을 정해주셨어요 (일관성 제약).
  2. 내가 1만 원밖에 없는데, 5만 원짜리 로봇을 장바구니에 담고 결제 버튼(트랜잭션)을 눌러버렸죠.
  3. 그러면 삐빅! 하고 빨간불이 켜지면서 "엄마가 정한 규칙 위반이야!" 하고 계산원이 나를 집으로 돌려보낸답니다! (일관성 유지)