컴퓨터·소프트웨어

트랜잭션과 ACID란? 데이터 무결성을 지키는 네 가지 원칙

2026-10-19 00:13
트랜잭션과 ACID란? 데이터 무결성을 지키는 네 가지 원칙 representative image

트랜잭션은 여러 데이터베이스 작업을 하나의 단위로 처리해 일부만 반영되는 문제를 막습니다. ACID는 트랜잭션이 전부 성공하거나 전부 취소되고, 유효한 데이터 상태를 유지하며, 동시 작업과 장애에도 결과를 보존하도록 설명하는 네 가지 원칙입니다.


📌 핵심 5줄 요약

1. 트랜잭션은 여러 SQL 작업을 하나의 논리적 작업 단위로 묶는 기능입니다.

2. 원자성은 모든 작업이 성공하거나 아무 작업도 반영되지 않게 보장합니다.

3. 일관성은 트랜잭션 전후로 데이터베이스의 규칙과 제약조건이 유지되도록 합니다.

4. 고립성은 동시에 실행되는 트랜잭션이 서로의 중간 결과를 잘못 읽지 않게 합니다.

5. 지속성은 커밋된 결과가 장애나 재시작 뒤에도 남도록 보장합니다.


📌 목차

01 | 트랜잭션의 기본 개념

02 | ACID가 필요한 이유

03 | 원자성의 의미

04 | 일관성의 의미

05 | 고립성의 의미

06 | 지속성의 의미

07 | 결제와 재고 차감 사례

08 | COMMIT과 ROLLBACK

09 | 트랜잭션 경계 설정

10 | 격리 수준의 차이

11 | 동시성 문제와 락

12 | 장시간 트랜잭션의 위험

13 | 분산 시스템에서의 한계


01 | 트랜잭션의 기본 개념

트랜잭션은 데이터베이스에서 함께 성공하거나 함께 실패해야 하는 작업의 묶음입니다. 하나의 SQL만 포함할 수도 있고, 여러 테이블에 대한 INSERT·UPDATE·DELETE를 함께 포함할 수도 있습니다.

대표적인 흐름은 트랜잭션 시작, 데이터 변경, 검증, 커밋 또는 롤백입니다. 커밋은 변경 내용을 확정하는 동작이고, 롤백은 트랜잭션 시작 전 상태로 되돌리는 동작입니다.


02 | ACID가 필요한 이유

데이터베이스 작업이 항상 한 번에 성공하는 것은 아닙니다. 애플리케이션 오류, 네트워크 단절, 서버 재시작, 동시 요청이 발생하면 여러 작업 중 일부만 처리될 수 있습니다.

예를 들어 계좌 이체에서 출금만 성공하고 입금이 실패하면 금액이 사라진 것처럼 보일 수 있습니다. 트랜잭션은 이런 부분 반영을 막고 시스템이 복구 가능한 상태를 유지하도록 돕습니다. ACID의 네 가지 속성은 트랜잭션의 예측 가능성과 장애 대응을 설명하는 기본 기준입니다.


03 | 원자성의 의미

원자성은 트랜잭션을 더 이상 나눌 수 없는 하나의 작업처럼 처리하는 성질입니다. 트랜잭션에 포함된 작업이 모두 성공하면 커밋하고, 중간에 하나라도 실패하면 전체 변경을 취소합니다.

출금과 입금 예시

계좌 A에서 금액을 차감하고 계좌 B에 같은 금액을 더하는 작업은 하나의 트랜잭션으로 묶어야 합니다. 출금 후 입금 단계에서 오류가 발생하면 출금도 롤백되어야 합니다.

원자성은 애플리케이션이 모든 실패 상황을 직접 되돌리는 부담을 줄여주지만, 실제로 어떤 작업을 하나의 트랜잭션으로 묶을지는 개발자가 결정해야 합니다.


04 | 일관성의 의미

일관성은 트랜잭션이 데이터베이스를 하나의 유효한 상태에서 다른 유효한 상태로 이동시키는 성질입니다. 여기서 유효한 상태는 기본키, 외래키, NOT NULL, UNIQUE, CHECK 같은 데이터베이스 제약조건과 서비스의 업무 규칙을 모두 고려한 상태입니다.

예를 들어 재고 수량이 음수가 될 수 없는 서비스라면 재고 차감 후에도 해당 규칙이 유지되어야 합니다. 다만 데이터베이스가 모든 업무 규칙을 자동으로 이해하는 것은 아니므로, 애플리케이션 검증과 제약조건 설계가 함께 필요합니다. 일관성은 원자성과 다릅니다. 모든 변경을 한꺼번에 반영하더라도 그 결과가 업무 규칙을 위반하면 일관성이 보장됐다고 보기 어렵습니다.


05 | 고립성의 의미

고립성은 동시에 실행되는 트랜잭션이 서로의 처리 중간 상태에 부적절하게 영향을 받지 않도록 하는 성질입니다. 한 트랜잭션이 아직 커밋하지 않은 변경을 다른 트랜잭션이 읽으면 잘못된 판단을 할 수 있습니다.

고립성이 충분하지 않으면 아직 취소될 수 있는 값을 읽는 더티 리드, 같은 트랜잭션 안에서 같은 조회 결과가 달라지는 반복 불가능 읽기, 조건에 맞는 행이 새로 나타나는 팬텀 리드가 발생할 수 있습니다.


06 | 지속성의 의미

지속성은 트랜잭션이 커밋된 뒤 시스템 장애가 발생해도 확정된 결과가 사라지지 않는 성질입니다. 데이터베이스는 일반적으로 로그, 저장장치 기록, 장애 복구 절차 등을 활용해 커밋 결과를 복원합니다.

다만 지속성의 실제 수준은 데이터베이스 설정뿐 아니라 저장장치, 운영체제, 복제 구성, 백업 정책과도 관련됩니다. 따라서 커밋이 성공했다는 응답만 확인할 것이 아니라 장애 발생 후 복구와 백업 복원 절차도 검증해야 합니다.


07 | 결제와 재고 차감 사례

상품 주문을 예로 들면 주문 생성, 결제 상태 기록, 재고 차감은 서로 밀접하게 연결됩니다. 같은 데이터베이스 안에서 반드시 함께 처리되어야 하는 변경이라면 하나의 트랜잭션으로 묶는 방식을 검토할 수 있습니다.

주문 생성은 성공했지만 재고 차감이 실패한 경우 주문을 취소할지, 재고를 다시 확보할지, 별도의 보상 작업을 실행할지 정책을 정해야 합니다. 특히 외부 결제 시스템이나 배송 시스템까지 포함하면 하나의 데이터베이스 트랜잭션만으로 전체 과정을 원자적으로 되돌리기 어렵습니다.


08 | COMMIT과 ROLLBACK

COMMIT은 현재 트랜잭션의 변경을 확정합니다. 커밋 이후에는 일반적인 롤백 명령으로 이미 확정된 변경을 취소할 수 없으므로, 취소가 필요하면 별도의 보정 작업이나 취소 트랜잭션을 설계해야 합니다.

ROLLBACK은 트랜잭션 안에서 수행한 변경을 취소합니다. 예외가 발생했을 때 롤백을 빠뜨리면 일부 변경이 남을 수 있으므로, 오류 처리 경로에서 커밋과 롤백의 위치를 명확히 확인해야 합니다.


09 | 트랜잭션 경계 설정

트랜잭션 경계는 어디서 시작하고 어디서 끝낼지를 정하는 기준입니다. 일반적으로 하나의 업무 요청에서 함께 성공하거나 실패해야 하는 데이터 변경을 경계 안에 포함합니다.

반대로 사용자 입력을 기다리거나 외부 API 응답을 기다리는 긴 작업까지 데이터베이스 트랜잭션으로 묶으면 잠금이 오래 유지되고 다른 요청이 대기할 수 있습니다. 데이터 조회와 변경, 검증, 커밋의 흐름을 짧고 명확하게 설계하는 것이 중요합니다.


10 | 격리 수준의 차이

격리 수준은 동시에 실행되는 트랜잭션이 서로의 데이터를 어느 정도까지 볼 수 있는지를 정하는 설정입니다. 일반적으로 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE 같은 수준이 사용됩니다.

격리 수준특징
READ UNCOMMITTED커밋되지 않은 변경을 읽을 가능성이 있어 가장 낮은 수준입니다.
READ COMMITTED커밋된 데이터만 읽도록 하며 조회 시점에 따라 결과가 달라질 수 있습니다.
REPEATABLE READ같은 트랜잭션 안에서 읽은 데이터의 반복성을 높이는 수준입니다.
SERIALIZABLE동시 작업을 직렬 실행에 가까운 결과로 제한하지만 충돌과 대기가 늘어날 수 있습니다.

지원 방식과 기본값은 데이터베이스 제품에 따라 다릅니다. 예를 들어 MySQL InnoDB는 네 가지 격리 수준을 지원하고 기본 격리 수준으로 REPEATABLE READ를 사용합니다. 따라서 제품 문서와 실제 운영 설정을 함께 확인해야 합니다.


11 | 동시성 문제와 락

여러 트랜잭션이 같은 행이나 범위를 동시에 변경하면 충돌이 발생할 수 있습니다. 데이터베이스는 잠금, 행 버전 관리, 스냅샷 등의 방법으로 충돌을 제어합니다.

잠금은 데이터 보호에 도움이 되지만 트랜잭션이 오래 유지되면 다른 요청이 대기하거나 교착 상태가 발생할 수 있습니다. 교착 상태는 서로가 상대방이 가진 자원을 기다리는 상황이므로, 데이터 접근 순서를 통일하고 실패 시 재시도할 수 있도록 설계하는 것이 일반적인 대응입니다.


12 | 장시간 트랜잭션의 위험

트랜잭션이 길어질수록 잠금 유지 시간, 로그 증가, 연결 점유, 다른 요청의 대기 시간이 늘어날 수 있습니다. 특히 대량 조회나 외부 서비스 호출을 트랜잭션 안에 넣으면 성능 문제가 커질 수 있습니다.

트랜잭션 안에서는 꼭 필요한 데이터베이스 작업만 수행하고, 네트워크 호출이나 파일 처리처럼 시간이 예측하기 어려운 작업은 가능하면 분리합니다. Microsoft 문서도 동시성이 중요한 환경에서 잠금 경합을 줄이기 위해 트랜잭션을 가능한 짧게 유지할 것을 안내합니다.


13 | 분산 시스템에서의 한계

하나의 데이터베이스 안에서는 ACID 트랜잭션을 적용하기 비교적 쉽지만, 여러 서비스와 데이터베이스가 연결되면 문제가 복잡해집니다. 각 서비스가 별도의 데이터 저장소를 사용하면 하나의 로컬 트랜잭션으로 모든 변경을 동시에 커밋하거나 롤백하기 어렵습니다.

이런 환경에서는 이벤트, 재시도, 멱등성, 보상 작업을 조합하는 방식이 사용됩니다. 대표적으로 사가 패턴은 각 서비스의 로컬 트랜잭션을 순서대로 실행하고, 중간 단계가 실패하면 이전 작업을 되돌리는 보상 트랜잭션을 수행합니다. 이는 단일 데이터베이스의 ACID와 동일한 보장이 아니므로, 최종 일관성과 실패 처리 정책을 별도로 설계해야 합니다.


☑ 체크리스트

트랜잭션을 설계하거나 장애를 점검할 때는 다음 항목을 확인하면 됩니다.

  • 함께 성공하거나 실패해야 하는 작업이 하나의 트랜잭션에 포함되어 있는가
  • 예외가 발생했을 때 모든 변경이 롤백되는가
  • 기본키·외래키·유일성·범위 제한 등 데이터 규칙이 적용되어 있는가
  • 동시에 같은 데이터를 변경할 때 더티 리드와 갱신 충돌을 방지하는가
  • 업무 특성에 맞는 격리 수준을 선택했는가
  • 트랜잭션 안에서 외부 API 호출이나 불필요한 대기 작업을 수행하지 않는가
  • 장애 후 커밋 결과를 복구하고 백업을 복원하는 테스트를 해보았는가

📖 자주하는 질문 Q&A

트랜잭션과 ACID는 같은 뜻인가요?

같은 뜻은 아닙니다. 트랜잭션은 여러 작업을 묶는 실행 단위이고, ACID는 그 트랜잭션이 지켜야 할 네 가지 신뢰성 원칙입니다.

ACID를 적용하면 데이터가 항상 완벽하게 안전한가요?

아닙니다. 데이터베이스 내부 트랜잭션의 안정성을 높여주지만, 잘못된 업무 규칙, 외부 시스템 장애, 잘못된 백업 설정, 애플리케이션 오류까지 자동으로 해결하지는 않습니다.

격리 수준은 무조건 높게 설정해야 하나요?

무조건 그렇지는 않습니다. 높은 격리 수준은 일관성과 재현성을 높일 수 있지만 잠금과 대기 시간이 늘어날 수 있습니다. 데이터의 중요도와 동시 요청량을 기준으로 선택하고 실제 충돌을 검증해야 합니다.

마이크로서비스에서도 ACID를 사용할 수 있나요?

각 서비스가 관리하는 데이터베이스 내부에서는 사용할 수 있습니다. 다만 여러 서비스의 변경을 하나의 트랜잭션으로 묶는 것은 어렵기 때문에 이벤트와 보상 작업을 활용한 별도 일관성 설계가 필요합니다.


📝 마무리

트랜잭션은 데이터 변경을 하나의 작업 단위로 묶고, ACID는 그 작업이 부분 반영·잘못된 동시 처리·장애로부터 안전하도록 설명하는 기준입니다. 원자성·일관성·고립성·지속성을 각각 구분해 이해하면 결제, 주문, 재고, 회원 정보처럼 중요한 기능의 오류 처리와 데이터 무결성을 더 정확하게 설계할 수 있습니다.

#트랜잭션 #ACID #데이터베이스 #데이터무결성 #원자성 #일관성 #고립성 #지속성 #커밋 #롤백 #데이터베이스기초 #DBMS #SQL #관계형데이터베이스 #트랜잭션관리 #동시성제어 #트랜잭션격리수준 #락 #동시성 #더티리드 #반복불가능읽기 #팬텀리드 #직렬화가능성 #데이터정합성 #데이터복구 #로그 #장애복구 #분산트랜잭션 #마이크로서비스 #개발자기초