티스토리 뷰

300x250

트랜잭션(Transaction)이란? ACID와 격리수준까지 쉽게 이해하기

데이터베이스를 공부하다 보면 트랜잭션(Transaction)ACID는 거의 반드시 만나게 됩니다. 그런데 처음 보면 용어 자체가 조금 딱딱해서, “대충 중요한 개념인 것 같은데 정확히는 모르겠다”는 상태로 넘어가기 쉽습니다.

하지만 트랜잭션은 생각보다 어렵지 않습니다. 오히려 실무에서는 굉장히 직관적인 개념입니다.

먼저 핵심부터
트랜잭션하나의 작업처럼 묶어서 처리해야 하는 SQL 실행 단위입니다.
중간에 문제가 생기면 전부 취소(ROLLBACK)하고, 문제가 없으면 한 번에 반영(COMMIT)합니다.
ACID는 이런 트랜잭션이 지켜야 할 핵심 성질입니다.

이번 글에서는 트랜잭션이 왜 필요한지, COMMITROLLBACK은 무엇인지, ACID는 어떻게 이해하면 되는지, 그리고 실무에서 자주 함께 나오는 격리수준(Isolation Level) 까지 초보도 이해하기 쉽게 정리해보겠습니다.

트랜잭션은 왜 필요할까?
여러 SQL이 함께 성공하거나 함께 실패해야 할 때가 많기 때문입니다.

예를 들어 은행 이체를 생각해보겠습니다.

  1. A 계좌에서 10만 원 출금
  2. B 계좌에 10만 원 입금

이 작업은 사실상 하나의 업무입니다. 그런데 만약 첫 번째 SQL은 성공하고, 두 번째 SQL은 실패하면 어떻게 될까요?

  • A 계좌에서는 돈이 빠졌는데
  • B 계좌에는 돈이 안 들어가는

심각한 데이터 불일치가 발생합니다.

그래서 데이터베이스는 이런 여러 작업을 하나로 묶어서 처리할 수 있어야 합니다. 그 묶음이 바로 트랜잭션입니다.

한 줄로 보면
트랜잭션은 여러 작업을 하나의 논리적 단위로 묶어서 처리하는 장치입니다.
COMMIT과 ROLLBACK은 무엇일까?
트랜잭션을 이해할 때 가장 먼저 익혀야 하는 두 가지 동작입니다.

트랜잭션에는 대표적으로 두 가지 결과가 있습니다.

COMMIT

문제가 없을 때, 지금까지의 변경 내용을 최종 반영합니다.

ROLLBACK

문제가 생겼을 때, 지금까지의 변경 내용을 전부 취소합니다.

예를 들어 아래처럼 생각하면 쉽습니다.

BEGIN;
UPDATE account SET balance = balance - 100000 WHERE id = 'A';
UPDATE account SET balance = balance + 100000 WHERE id = 'B';
COMMIT;

중간에 오류가 나면 이렇게 처리할 수 있습니다.

BEGIN;
UPDATE account SET balance = balance - 100000 WHERE id = 'A';
UPDATE account SET balance = balance + 100000 WHERE id = 'B';
ROLLBACK;
핵심 포인트
성공하면 COMMIT, 문제가 생기면 ROLLBACK이라고 기억하면 됩니다.
ACID는 무엇일까?
트랜잭션이 믿을 수 있게 동작하려면 지켜야 할 4가지 성질이 있습니다.

ACID는 트랜잭션의 핵심 성질 4가지를 말합니다.

  • Atomicity : 원자성
  • Consistency : 일관성
  • Isolation : 격리성
  • Durability : 지속성

이 4개를 하나씩 보면 훨씬 쉽습니다.

A - 원자성(Atomicity)
전부 성공하거나, 전부 실패해야 한다는 뜻입니다.

원자성은 트랜잭션 안에 있는 작업들이 쪼개져서 일부만 반영되면 안 된다는 의미입니다.

예를 들어 계좌이체에서 출금만 되고 입금이 안 되면 안 됩니다. 둘 다 성공하거나, 둘 다 취소되어야 합니다.

원자성 한 줄 정리
All or Nothing 개념입니다. 일부만 성공하는 상태를 허용하지 않습니다.
C - 일관성(Consistency)
트랜잭션 전후로 데이터 규칙이 깨지지 않아야 합니다.

일관성은 트랜잭션이 끝난 뒤에도 데이터가 정상적인 규칙을 유지해야 한다는 뜻입니다.

예를 들어,

  • 잔액은 음수가 되면 안 된다
  • 주문 상태는 정의된 값만 들어가야 한다
  • FK 관계가 깨지면 안 된다

같은 규칙이 계속 지켜져야 합니다.

즉, 트랜잭션이 끝난 뒤 데이터가 이상한 상태가 되어서는 안 됩니다.

일관성 한 줄 정리
트랜잭션 전후로 데이터의 규칙과 제약 조건이 유지되어야 한다는 의미입니다.
I - 격리성(Isolation)
동시에 실행되는 트랜잭션끼리 서로 너무 엉키지 않게 해야 합니다.

격리성은 여러 트랜잭션이 동시에 실행될 때, 서로의 작업이 이상하게 섞여 보이지 않도록 하는 성질입니다.

예를 들어,

  • 아직 COMMIT도 안 된 데이터를 다른 트랜잭션이 읽어버리면 문제가 생길 수 있습니다.
  • 같은 데이터를 동시에 수정하면서 꼬일 수도 있습니다.

그래서 DBMS는 격리 수준(Isolation Level)을 통해 이런 충돌을 조절합니다.

초보 단계에서는 우선 이렇게만 이해하면 충분합니다.

여러 사용자가 동시에 작업하더라도, 트랜잭션은 서로 너무 함부로 간섭하면 안 된다.

초보 관점 포인트
격리성은 쉽게 말해 동시 실행 중인 작업끼리 서로의 중간 상태를 함부로 건드리지 않게 하는 장치입니다.
D - 지속성(Durability)
성공한 트랜잭션 결과는 시스템 장애가 나도 유지되어야 합니다.

지속성은 한 번 COMMIT된 결과는 장애가 발생해도 사라지지 않아야 한다는 뜻입니다.

예를 들어 결제가 성공했다고 사용자에게 보여줬는데, 서버가 재시작된 뒤 결제 데이터가 사라지면 큰 문제가 됩니다. 그래서 DBMS는 로그와 디스크 반영 등을 통해 COMMIT된 데이터가 유지되도록 보장합니다.

지속성 한 줄 정리
COMMIT된 결과는 믿고 써도 되는 상태여야 합니다.
격리수준(Isolation Level)은 왜 중요할까?
트랜잭션의 격리성은 실제로는 격리수준 설정을 통해 조절됩니다.

격리성 이야기를 할 때 꼭 같이 나오는 것이 바로 격리수준(Isolation Level)입니다.

트랜잭션은 서로 간섭하지 않아야 하지만, 현실에서는 성능도 중요합니다. 그래서 DBMS는 무조건 완벽하게 막는 방식 대신, 어느 정도까지 읽기 충돌을 허용할지 단계별로 선택할 수 있게 해둡니다.

쉽게 말하면,

  • 격리를 강하게 하면 데이터는 더 안전하게 보이지만 성능과 동시성이 떨어질 수 있고
  • 격리를 약하게 하면 성능은 좋아질 수 있지만 이상한 읽기 현상이 생길 수 있습니다.
핵심 이해
격리성은 개념이고, 격리수준은 그 개념을 DBMS에서 실제로 얼마나 강하게 적용할지 정하는 설정이라고 보면 됩니다.
트랜잭션 격리수준 4단계
보통 아래 4단계를 많이 정리합니다.

1) READ UNCOMMITTED

가장 낮은 격리수준입니다. 아직 COMMIT되지 않은 데이터도 읽을 수 있는 상태라서, 이른바 Dirty Read가 발생할 수 있습니다.

예를 들어 다른 트랜잭션이 수정만 해두고 나중에 ROLLBACK했는데, 그 중간값을 내가 읽어버릴 수 있습니다.

2) READ COMMITTED

다른 트랜잭션이 COMMIT한 데이터만 읽을 수 있는 수준입니다. Dirty Read는 막을 수 있지만, 같은 SELECT를 두 번 했을 때 중간에 다른 트랜잭션이 COMMIT하면 결과가 달라질 수 있습니다. 이런 현상을 Non-Repeatable Read라고 합니다.

3) REPEATABLE READ

한 트랜잭션 안에서 같은 행(Row)을 여러 번 읽어도 처음 읽은 결과가 반복해서 유지되도록 보장하는 수준입니다. 그래서 Non-Repeatable Read를 막는 데 유리합니다.

다만 범위 조회에서는 새 행이 끼어드는 Phantom Read 같은 이슈를 완전히 막지 못하는 경우가 있습니다. (DBMS 구현마다 차이가 있습니다.)

4) SERIALIZABLE

가장 높은 격리수준입니다. 여러 트랜잭션이 동시에 실행되더라도 거의 순차 실행처럼 보이게 만듭니다.

데이터 정합성 측면에서는 가장 안전하지만, 잠금이 많아지고 동시 처리 성능이 떨어질 수 있어서 항상 무조건 좋은 선택은 아닙니다.

격리수준 특징 이해 포인트
READ UNCOMMITTED COMMIT 전 데이터도 읽을 수 있음 Dirty Read 위험
READ COMMITTED COMMIT된 데이터만 읽음 Dirty Read 방지
REPEATABLE READ 같은 행 조회 결과를 유지 Non-Repeatable Read 완화
SERIALIZABLE 거의 순차 실행처럼 처리 가장 안전하지만 성능 부담 큼
면접/실무에서 자주 같이 나오는 용어
격리수준을 설명할 때는 보통 Dirty Read, Non-Repeatable Read, Phantom Read를 함께 묶어서 이해하면 좋습니다.
ACID를 표로 보면 더 쉽다
이름보다 의미로 기억하는 편이 훨씬 오래 갑니다.
요소 의미 쉽게 이해하면
A Atomicity 전부 성공하거나 전부 취소
C Consistency 규칙이 깨지지 않는 상태 유지
I Isolation 동시 작업끼리 함부로 간섭하지 않음
D Durability COMMIT된 결과는 유지됨
정말 중요한 기준
트랜잭션은 데이터 정합성을 지키기 위한 핵심 장치입니다. 단순 편의 기능이 아니라, 서비스 신뢰도와 직접 연결됩니다.
초보가 자주 하는 오해
처음에는 COMMIT/ROLLBACK만 기억하고 넘어가기 쉬운데, 몇 가지 오해를 같이 잡아두는 게 좋습니다.

1) SQL 한 줄 = 항상 트랜잭션?

단일 SQL도 하나의 트랜잭션처럼 처리될 수 있지만, 보통 우리가 중요하게 보는 것은 여러 작업을 묶는 비즈니스 트랜잭션입니다.

2) COMMIT만 하면 무조건 끝?

아닙니다. 중간 설계가 잘못되면 애초에 비정상 데이터가 들어갈 수도 있습니다.

3) ACID는 외우기만 하면 된다?

아닙니다. 계좌이체, 주문결제, 재고차감 같은 실제 사례에 연결해서 이해해야 오래 갑니다.

초보 기준 핵심 정리
트랜잭션은 여러 작업을 안전하게 하나처럼 처리하기 위한 장치이고, ACID는 그 장치가 믿을 수 있게 동작하도록 하는 핵심 원칙입니다.
실무에서는 어떻게 보면 좋을까?
실무에서는 결국 “이 작업을 어디까지 하나로 묶어야 하는가?”가 중요합니다.

실무에서는 보통 이런 작업에서 트랜잭션이 중요합니다.

  • 결제 처리
  • 계좌 이체
  • 주문 생성 + 재고 차감
  • 게시글 작성 + 첨부파일 메타 저장
  • 회원 가입 + 권한 부여

즉, 여러 SQL이 함께 성공해야 의미가 있는 작업은 거의 모두 트랜잭션 대상입니다.

실무 팁
트랜잭션을 볼 때는 SQL 개수보다 비즈니스적으로 하나여야 하는 작업인가?를 먼저 생각하면 판단이 훨씬 쉬워집니다.
마무리 정리
트랜잭션은 여러 작업을 하나의 단위로 묶어서 안전하게 처리하기 위한 기능입니다. 성공하면 COMMIT, 실패하면 ROLLBACK으로 제어하고, 이 과정이 믿을 수 있게 동작하도록 하는 원칙이 바로 ACID입니다.
트랜잭션 = 여러 작업을 하나처럼 처리하는 단위
COMMIT = 최종 반영
ROLLBACK = 전부 취소
ACID = 트랜잭션이 지켜야 할 4가지 핵심 성질
격리수준 = 동시 실행 충돌을 어디까지 허용할지 정하는 기준

초보 단계에서는 우선 이렇게 기억하면 충분합니다.

트랜잭션은 함께 처리돼야 하는 작업을 하나로 묶는 장치이고, ACID는 그 작업이 안전하고 믿을 수 있게 동작하도록 보장하는 원칙입니다.
728x90
댓글