0. 트랜잭션(Transaction)개념과 특성(ACID)

래퍼런스

https://le2ksy.tistory.com/4

데이터 무결성이란?

시스템의 전체적인 생명 주기에서 데이터의 정확성과 일관성을 유지하고 보증하는 것을 의미한다. 트랜잭션은 데이터 무결성을 보장해주는 핵심 개념이다.

1. 트랜잭션(Transaction)개념

트랜잭션에 대한 정의는 데이터베이스에서 상태를 변화시키기 위해 수행하는 논리적 작업 단위를 의미한다. 트랜잭션은 데이터의 무결성을 보장하기 위해, 하나의 단위로 실행되는 연산 묶음을 표현할 수 있다. 그리고 이 묶음 속 연산들은 데이터 무결성을 위해 전체가 모두 성공하거나 실패해야 한다.

START TRANSACTION; 
UPDATE ACCOUNT SET amount = amount + 1000 WHERE user_id = 1; --사용자1에게 입금
UPDATE ACCOUNT SET amount = amount - 1000 WHERE user_id = 2; --사용자2에서 출금
COMMIT;

2. 트랜잭션의 연산 종류

트랜잭션의 연산은 COMMIT과 ROLLBACK이 있다. COMMIT은 트랜잭션 내부의 모든 연산이 성공한다면 이를 실제 DB에 반영하는 것을 의미하고, ROLLBACK은 하나라도 실패하면 반영하지 않고 모든 연산을 이전으로 되돌리는 것을 의미한다.

3. 트랜잭션의 상태

연산 진행에 따른 트랜잭션의 상태 흐름도는 다음과 같다.
Pasted image 20260520163052.png

여기서 aborted 상태 이후에는 두 가지 선택지가 있다. 트랜잭션을 종료하거나 트랜잭션을 재실행 시킬 수 있다. 이때 롤백의 원인이 이를 결정하는데, 트랜잭션 자체의 논리적인 오류인 경우나 데이터가 없다면 종료되지만, 그렇지 않다면 트랜잭션이 재시작된다.

4. 트랜잭션의 특성 ACID

앞서 살펴봤듯이 트랜잭션이 해결하는 문제는 데이터 무결성이다. 그렇기에 연산 단위가 묶일 필요가 있었던 것도 무결성을 지키기 위함이었고, 롤백을 제공하는 것 또한 데이터 무결성 때문이다. 이 데이터 무결성이라는 목표을 의식하며 트랜잭션이 지켜야 할 특성 4가지를 살펴보자.

4.1 원자성(Atomicity)

트랜잭션으로 묶인 연산 집합은 부분적으로 실행되다가 중단되지 않는다를 보장하는 것을 의미한다. 즉 쉽게 말해 트랜잭션 내부의 모든 연산은 모두 실행되거나 모두 실패하거나 둘 중 하나이다.

이 또한 무결성을 위함이다. 만약 사용자 A가 사용자 B에게 계좌를 출금한 상황을 예로 들어보자.
Pasted image 20260520164838.png
사용자 A의 계좌에서는 10만원이 빠져나갔지만, 사용자 B의 계좌에는 10만원이 들어오지 않는 오류가 발생할 수 있다. 이런 데이터 무결성이 깨지는 경우를 보완하기 위해, 트랜잭션은 위의 모든 과정을 하나의 트랜잭션으로 묶고, 하나의 연산이라도 실패한 경우 이미 실행된 연산을 모두 원복한다. 즉, 트랜잭션 내부 연산들은 하나의 작업으로 취급되어 원자성이 보장되도록 한다.

4.2 일관성(Consistency)

트랜잭션이 성공적으로 종료되었을 때, 항상 데이터베이스의 상태를 언제나 일관성 있는 상태로 유지하는 것을 의미한다. 예를 들어, 사용자의 계좌의 잔액이 마이너스가 되는 것이 무결성 제약 조건으로 되어 있다면, 해당 트랜잭션은 반드시 실패되어야 한다. 즉, 데이터베이스의 상태가 일관성 있도록 유지되도록 하는 것도 트랜잭션이 고려해야 할 요소이다. 넓은 의미에서는 결국 무결성을 보장하는 것이다.

일관성이라는 표현이 조금 모호하게 다가올 수 있을 것 같다. 트랜잭션의 일관성(Consistency)을 쉽게 표현하면,

트랜잭션이 실행되기 전과 실행된 후에 데이터베이스가 항상 정해진 규칙과 제약 조건을 만족하는 상태여야 한다는 성질

즉, 넓은 의미에서 규칙과 제약 조건이 통일된 상태를 일관성 있다고 표현한다.

무결성과 일관성을 정리하자면, 무결성은 데이터가 지켜야 할 규칙을 의미하고, 일관성은 그 규칙이 지켜진 상태를 의미한다. 즉 쉽게 말해 무결성은 교통 법규를 의미한다면, 일관성은 교통법규가 지켜지고 있는 도로 상태를 의미한다.

4.3 격리성(Isolation) (혹은 독립성)

동시에 실행되는 여러 트랜잭션들은 서로 독립적이다. 즉, 트랜잭션이 실행될 때 다른 트랜잭션이 그 작업 사이에 못 끼어들도록 보장한다. 트랜잭션 밖에서는 어떤 연산도 중간 단계 데이터를 볼 수 없음을 의미한다. 즉, 사용자 A의 계좌가 10만원이 줄어들고 사용자 B의 계좌에 아직 10만원이 들어오지 않은 그 순간, 다른 트랜잭션이 해당 데이터를 볼 수 없도록 보장해야 한다.

물론 트랜잭션만 건다고 해당 정합성이 항상 보장되는 것이 아니다. 실제 보장 범위는 데이터베이스 격리 수준이나 락 설정에 따라 좌우된다. 트랜잭션은 ACID 성질을 제공하지만, 실제 무결성 보장 정도는 제약 조건, 격리 수준, 락, 애플리케이션 로직에 따라 달라진다.

그래서 앞서 말한,

어떤 연산도 중간 단계 데이터를 볼 수 없음을 의미한다.

도 항상 정답은 아니다. 이 설명은 격리 수준의 Serializable 수준의 강한 격리에 가깝다. 일반적인 DB 격리 수준에서는 완전히 못끼워들기 보다는 중간 결과를 어디까지 보이게 할지 제어할 수 있다. 그리고 락과 같은 설정을 통해 정합성을 유지하는 것이 필요하다.

4.4 지속성(Durability)

성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다. 즉 시스템이 장애가 나도 성공적으로 수행된 트랜잭션은 반드시 데이터베이스에 영구적으로 반영되어야 한다.

일반적으로 트랜잭션은 로그의 형태로 저장된다. 그리고 로그가 저장되어야 COMMIT된 상태로 간주된다. 그래서 나중에 장애가 발생한다면, 로그 데이터를 통해 데이터베이스를 회복할 수 있다.

결과적으로 트랜잭션은 데이터 무결성을 지키기 위한 개념이며, 온전한 트랜잭션은 AICD를 만족해야 한다.
또한 회복이나, 병행 제어를 통해 데이터베이스를 항상 일관된 상태(무결한 상태)로 유지시켜주는 핵심 존재이다.