194. 일관성 (Consistency) - 트랜잭션 전후에 데이터베이스 제약조건(무결성) 유지 - 병행제어/무결성 제약조건 보장

핵심 인사이트: (192번 ACID 심화) 은행 DB에 "모든 고객의 잔고는 마이너스(음수)가 될 수 없다!"라는 헌법(제약조건)을 박아놨다. 내 잔고가 1만 원 있는데, 내가 쿠팡에서 2만 원짜리 신발 결제 버튼(트랜잭션)을 욱여넣었다. 시스템 에러도 안 났고 서버 전원도 안 꺼졌다(원자성 만족). 그래서 결제가 성공(COMMIT)해 버려서 내 잔고가 '-1만 원'이 됐다?! "야! 쿼리 에러 안 나고 끝까지 성공했다고 도장 찍어주면 다냐!! 트랜잭션이 성공적으로 끝났더라도, 그 결과물이 우리 은행이 처음 세워둔 '법(잔고는 0 이상이어야 한다)'을 어기면 그건 쓰레기 덩어리야!! 성공하기 직전에 무조건 법을 어겼는지 깐깐하게 심사해서, 어겼으면 얄짤없이 빠꾸(ROLLBACK) 먹여서 시스템의 정상 상태를 영원히 수호해라!!" 트랜잭션의 결과가 합법적인지 감시하는 헌법 재판소, 일관성이다.

Ⅰ. 무결성(Integrity)과 데이터베이스의 건강

  • 139번 문서들에서 배울(예정인) '무결성 제약조건'은 DB의 법입니다.
    • 예: "나이 컬럼은 0~150 사이 숫자만 가능 (도메인 무결성)"
    • 예: "주민번호는 절대 겹치면 안 됨 (개체 무결성)"
  • 트랜잭션이 돌기 전의 DB는 이 모든 법을 완벽하게 만족하는 '건강한 정상 상태(Consistent State)'입니다.

Ⅱ. 일관성 (Consistency)의 절대 정의 🌟

  • 개념: 트랜잭션이 수행되기 전에 데이터베이스가 일관된(모순이 없는) 상태였다면, 트랜잭션 수행이 100% 완료된 후에도 데이터베이스는 반드시 일관된(모순이 없는) 상태를 그대로 유지해야 한다는 성질입니다.
  • 즉, 트랜잭션 중간에 지지고 볶는 동안에는 잠시 법을 어겨도(일시적 불일치) 상관없지만, "나 일 다 끝났소!(COMMIT)" 하고 보고하는 그 마지막 순간만큼은 무조건 모든 제약조건을 완벽히 만족하는 합법적 상태로 얌전히 돌아와 있어야 합니다.

Ⅲ. 일관성이 깨지는 시나리오와 수호자들 🌟 핵심 🌟

일관성(C)은 지 혼자 버티는 게 아니라, 개발자와 DB의 다른 기능들이 협력해서 지켜냅니다.

1. 트랜잭션 로직 자체의 붕괴 (개발자 책임)

  • 송금 트랜잭션 로직: A계좌 - 1만 원 하고 끝내버렸습니다. (B계좌에 + 1만 원 하는 쿼리를 개발자가 실수로 안 짰음)
  • 트랜잭션은 에러 없이 COMMIT 됩니다(원자성 통과). 하지만 세상의 돈 1만 원이 공중 분해되어 사라졌습니다! 은행의 '총금액 불변의 법칙'이라는 일관성이 박살 난 겁니다.
  • 수호자: 무결성 제약조건(트리거, Constraint)을 빡세게 걸어두어, 총합이 틀어지는 순간 DB 엔진이 분노하여 강제 ROLLBACK 시켜 방어합니다.

2. 동시성의 충돌 (병행제어 책임)

  • 내 잔고 1만 원. 나(A)와 엄마(B)가 동시에 카드를 긁었습니다.
  • A가 잔고를 1만 원으로 읽고 0원으로 깎는 찰나에, B도 1만 원으로 읽고 0원으로 깎았습니다. 둘 다 성공해 버려서 은행은 2만 원을 잃고 잔고는 0원이 되는 모순(Inconsistency)이 터집니다. (204번 모순성)
  • 수호자: 이 끔찍한 사태를 막기 위해, 195번에서 배울 **'격리성(Isolation)'**과 201번의 '병행 제어(Concurrency Control)' 기능이 칼을 뽑습니다. "동시에 들어오면 1명은 무조건 대기 타라(자물쇠 Lock)!"라고 줄을 세워버려 동시 충돌로 인한 일관성 붕괴를 원천 차단합니다.

Ⅳ. 궁극의 의미: 시스템의 논리적 무결성 보장

  • 원자성(A)이나 영속성(D)이 기계가 뻗는 하드웨어/시스템 에러에 대한 물리적 방어막이라면, 일관성(C)은 소프트웨어 비즈니스 로직과 데이터의 의미(Meaning) 자체가 썩어 문드러지지 않게 지켜주는 논리적 헌법 방어막입니다.

📢 섹션 요약 비유: 데이터베이스의 **일관성(Consistency)**은 스포츠 경기의 **'심판과 룰(규칙)'**입니다. 게임(트랜잭션)이 시작되기 전 모든 선수는 정해진 위치에 서 있습니다(정상 상태). 휘슬이 울리고 게임이 굴러가는 동안(트랜잭션 진행 중), 선수들이 몸싸움도 하고 공이 이리저리 날아다니는 난장판(일시적 불일치 상태)이 벌어집니다. 하지만 결국 슛을 때려 '골(COMMIT)'을 선언하려면, 무조건 '오프사이드 반칙이 없었는지, 손으로 공을 건드리지 않았는지(무결성 제약조건 만족)'를 심판이 칼같이 검증해야 합니다. 만약 공격수가 칼을 들고 수비수를 찔러서 골을 넣었다면? 골망을 갈랐다(연산 완료) 하더라도 심판이 호루라기를 불어 "반칙! 무효(ROLLBACK)!"를 선언하여 게임을 원래 상태로 되돌립니다. 트랜잭션이 아무리 기계적으로 잘 돌았어도, 그 결과물이 '합법적인 정상 상태'가 아니면 절대 인정하지 않고 시스템의 정의(무결성)를 100% 수호하는 최후의 판결 문지기입니다.