트랜잭션(Transaction)의 이해와 활용

ya·2025년 8월 7일

DataBase와 SQL

목록 보기
12/12
post-thumbnail

1. 트랜잭션

트랜잭션(Transaction)은 데이터베이스에서 하나의 논리적인 작업 단위를 의미합니다. 일반적으로 여러 개의 SQL 문장을 하나로 묶어 실행하며, 모두 성공하거나 하나라도 실패하면 전체 작업을 취소해야 하는 상황에서 사용됩니다.

예를 들어, 계좌 이체의 경우 출금과 입금이 함께 수행되어야 하므로, 둘 중 하나라도 실패하면 전체 작업을 롤백해야 합니다. 이처럼 데이터의 일관성과 무결성을 보장하기 위해 트랜잭션 개념이 필요합니다.


2. 트랜잭션의 특징 - ACID

1. Atomicity (원자성)

모든 작업이 하나의 단위로 수행되어야 하며, 중간에 일부만 수행되는 일은 없어야 합니다. 하나라도 실패하면 전체를 롤백(Rollback)합니다.

2. Consistency (일관성)

트랜잭션 수행 전과 수행 후의 데이터 상태가 항상 일관된 상태를 유지해야 합니다. 무결성 제약조건(Primary Key, Foreign Key 등)을 항상 만족해야 합니다.

3. Isolation (고립성)

여러 트랜잭션이 동시에 실행될 경우, 각 트랜잭션은 서로 간섭받지 않아야 합니다. 즉, 하나의 트랜잭션이 완료되기 전에는 그 중간 결과를 다른 트랜잭션에서 볼 수 없어야 합니다.

Isolation은 실제 DB 구현에서 완벽히 보장하기 어렵기 때문에 격리 수준(Isolation Level) 이라는 형태로 선택적으로 조정됩니다.

4. Durability (지속성)

트랜잭션이 성공적으로 커밋되면, 시스템이 장애를 겪더라도 결과는 영구적으로 보존되어야 합니다. 이를 위해 DBMS는 로그(Write-Ahead Logging)나 체크포인트 등을 활용합니다.


3. 트랜잭션 격리 수준 (Isolation Level)

격리 수준Dirty ReadNon-Repeatable ReadPhantom Read
Read Uncommitted❌ 발생✅ 발생✅ 발생
Read Committed✅ 방지❌ 발생✅ 발생
Repeatable Read✅ 방지✅ 방지❌ 발생
Serializable✅ 방지✅ 방지✅ 방지

1. Read Uncommitted

가장 낮은 격리 수준. 커밋되지 않은 데이터도 읽을 수 있어 Dirty Read가 발생합니다. 성능은 좋지만 데이터 정합성이 낮아 거의 사용되지 않습니다.

2. Read Committed

커밋된 데이터만 읽을 수 있어 Dirty Read는 방지되지만, 같은 데이터를 두 번 조회할 때 값이 달라지는 Non-Repeatable Read가 발생할 수 있습니다.
※ Oracle, SQL Server의 기본 격리 수준

3. Repeatable Read

동일한 데이터를 반복 조회해도 값이 변하지 않도록 보장합니다. 대부분의 변경 작업에는 잠금이 걸립니다.
단, Phantom Read(같은 조건의 조회인데 행 개수가 바뀜)는 발생할 수 있습니다.
※ MySQL InnoDB의 기본 격리 수준

4. Serializable

가장 높은 격리 수준. 트랜잭션을 직렬화한 것처럼 처리하여 모든 이상 현상을 방지합니다. 하지만 성능이 크게 저하되어 대량 트랜잭션 환경에서는 비효율적입니다.


4. 트랜잭션 이상 현상 (Anomalies)

  • Dirty Read: 커밋되지 않은 데이터를 읽음
  • Non-Repeatable Read: 같은 쿼리를 두 번 수행했을 때 결과가 달라짐
  • Phantom Read: 같은 조건의 쿼리인데 실행 시점마다 행의 수가 달라짐 (ex: WHERE age > 20)

5. 트랜잭션 생명 주기 (Lifecycle)

Active(활동)트랜잭션이 실행 중에 있는 상태, 연산들이 정상적으로 실행 중인 상태
Failed(실패)트랜잭션이 실행에 오류가 발생하여 중단된 상태
Aborted(철회)트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태
Partially Committed(부분 완료)트랜잭션이 마지막 연산까지 실행했지만, Commit 연산이 실행되기 직전의 상태
Committed(완료)트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태

6. 트랜잭션과 Lock

트랜잭션의 고립성을 보장하기 위해 DBMS는 다양한 Lock 메커니즘을 사용
경쟁 상태(race)를 막기 위해 DB가 레코드/페이지/테이블 등에 걸어두는 잠금.

  • Shared Lock (S-lock): 읽기용 잠금. 여러 트랜잭션이 동시에 공유 가능
  • Exclusive Lock (X-lock): 쓰기용 잠금. 해당 자원에 대해 단독 접근
  • Gap Lock, Range Lock: Phantom Read 방지용 잠금 (MySQL InnoDB)

※ 격리 수준에 따라 Lock의 범위와 강도가 달라지며, 무분별한 Lock은 데드락(Deadlock) 의 원인이 됩니다.


7. Lock의 실행

비관적 락(Pessimistic)

충돌이 자주 발생한다고 보고 DB 락을 사용. SELECT ... FOR UPDATE 같은 명령으로 락을 걸고 처리.
예: 은행 계좌 이체

BEGIN;
SELECT balance FROM accounts WHERE id=123 FOR UPDATE; -- 해당 행에 X 락
UPDATE accounts SET balance = balance - 100 WHERE id=123;
COMMIT; -- 락 해제
  • 장점: 데이터 무결성이 강하게 보장됨.
  • 단점: 락 대기/교착(deadlock) 발생 가능, 동시성 저하.

낙관적 락(Optimistic)

충돌이 드물다고 가정. 업데이트 시점에 충돌 검사.
예: version 컬럼 방식

-- 초기 테이블: id, data, version
UPDATE items
SET data = 'new', version = version + 1
WHERE id = 10 AND version = 3; -- 업데이트된 행 수가 0이면 충돌 -> 재시도
  • 장점: 락 보유 없음 → 동시성 우수.
  • 단점: 충돌이 잦으면 재시도 오버헤드 큼.

적용

-- 1. 세션 격리 수준 설정 (이 세션에서만 적용됨)
-- READ COMMITTED: 커밋된 데이터만 읽기, SELECT 시 오래 락 안 잡음
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 2. 트랜잭션 시작
START TRANSACTION;

-- 3. 특정 행에 배타락(X-Lock) 걸기
-- 'FOR UPDATE' → 해당 행을 다른 트랜잭션이 읽거나 수정 불가
-- 주로 읽고 바로 수정할 때 사용 (은행 계좌 이체 등)
SELECT balance 
FROM accounts 
WHERE id = 1 
FOR UPDATE;

-- 4. 데이터 수정
UPDATE accounts 
SET balance = balance - 100 
WHERE id = 1;

-- 5. 특정 행에 공유락(S-Lock) 걸기
-- 'LOCK IN SHARE MODE' → 읽기는 허용, 수정은 차단
-- 다른 트랜잭션이 이 행을 UPDATE/DELETE하려면 대기
SELECT * 
FROM accounts 
WHERE id = 2 
LOCK IN SHARE MODE;

-- 6. 트랜잭션 종료 (모든 락 해제)
COMMIT;

8. 트랜잭션과 Savepoint

트랜잭션 도중 중간 지점을 설정하여, 전체 롤백이 아닌 부분 롤백을 수행할 수 있게 합니다.

SAVEPOINT sp1;
-- 중간 처리
ROLLBACK TO sp1;

9. 트랜잭션과 Auto-commit

MySQL과 같은 DB는 기본적으로 Auto Commit이 활성화되어 있어, 각 SQL 문이 실행되면 자동으로 Commit 됩니다.
트랜잭션 단위로 묶고 싶다면, 다음과 같이 설정해야 합니다:

SET autocommit = 0;
BEGIN;
-- 여러 쿼리
COMMIT;

또는 JDBC에서 connection.setAutoCommit(false) 설정을 통해 수동 제어합니다.


10. 트랜잭션 실패 사례

  • 제약 조건 위반 (Primary Key, Foreign Key)
  • Deadlock 발생
  • 시스템 다운 / 장애
  • 타임아웃 초과

실패 시 DBMS는 자동 롤백하거나, 애플리케이션에서 수동으로 롤백해야 합니다.


11. RDB vs NoSQL – 트랜잭션 관점

항목RDBNoSQL
트랜잭션 지원강력한 ACID약한 일관성 (Eventually Consistent)
데이터 모델정형, 정규화된 테이블유연한 비정형 (문서, 키-값 등)
확장성수직 확장 중심(CPU, RAM, Disk 성능 업그레이드)수평 확장(노드 추가로 처리량 증가)에 유리
조인자유롭게 가능대부분 미지원 또는 비효율적
스키마 변경민감유연함

NoSQL은 일부 트랜잭션을 지원하기도 하나, 범위가 제한적이며 보통은 성능과 확장성 측면에서 일관성(Consistency)을 희생합니다.

profile
ya로그

0개의 댓글