CS

[Database] 트랜잭션 개념

sangyunpark 2023. 8. 14. 12:56

트랜잭션 개념

데이터 베이스 관리 시스템(DBMS)에서 여러 개의 작업을 하나의 논리적 단위로 묶어서 실행하고, 이 작업들이 모두 성공적으로 완료되거나 아무것도 완료되지 않은 상태를 나타내는 개념

여러 사용자가 동시에 데이터베이스를 접근하고 변경할 때 데이터의 일관성과 무결성을 보장하기 위해 사용되는 개념

ACID

Atomic(원자성)

All or Nothing, 모든 작업이 실행되거나 혹은 모두 실행되지 않아야 한다.

 

예시) A 계좌에서 B계좌로 잔액을 송금하는 경우

A계좌 잔액 줄이기 작업과 B계좌 잔액 늘리기 작업은 함께 성공하거나 함께 실패해야 한다.

 

Consistency(일관성)

모든 트랜잭션이 종료된 후에는 DB의 제약조건을 모두 지키고 있는 상태가 되어야 한다.

 

예시) 잔액은 0원 이상이다.

이를 위반하는 트랜잭션은 모두 중단된다.

 

Isolation(격리성)

트랜잭션은 다른 트랜잭션과 독립적으로 동작해야한다.

A 트랜잭션이 하는 일을 B 트랜잭션은 모르게 해야한다.

 

현실에서는? 완전한 격리성을 지켜주기 쉽지 않다!

성능과 안정성의 트레이드 오프 관계이 있는 부분

 

성능과 안정성의 트레이드 오프란?

시스템이나 제품에서 성능을 향상시키려면 안정성을 희생해야 하거나, 반대로 안정성을 높이려면 성능을 희생해야 하는 관계

 

READ_UNCOMMITTED > READ_COMMITTED > REPEATABLE_READ > SERIALIZABLE 순서로 성능은 떨어지고 격리성(고립성)은 증가한다.

 

격리성이 낮을때 일어나는 문제

Dirty read, Phantom read 등이 발생 가능

 

Dirty read란?

트랜잭션 격리 수준 중에서 가장 낮은 수준인 "Read Uncommitted" 수준에서 발생하는 문제

변경 후 아직 commit이 되지 않은 값을 읽고, Rollback이 된 후의 값을 다시 읽어 최종 결과 값이 상이한 현상

 

한 트랜잭션이 데이터를 읽을 때, 아직 커밋되지 않은 다른 트랜잭션의 변경사항 까지도 읽을 수 있다. 이로 인해서 다른 트랜잭션이 아직 완료되지 않았거나 롤백된 변경 사항도 읽을 수 있으므로 데이터의 일관성을 보장하지 못한다.

 

상황 예시

(1) A와 B는 같은 계좌에서 동시에 작업을 하는 상황
(2) A는 계좌 잔액이 $1000라고 읽는다.
(3) B가 아직 작업을 완료하지 않은 상황에서 계좌 잔액을 $500으로 변경하는 작업 진행
(4) A는 Dirty read로 인해 B의 변경 사항이 커밋되지 않았음에도 불구하고 변경된 잔액 $500을 읽음
(5) B가 작업을 롤백하거나 완료하는 순간, A가 읽은 잔액은 일관성이 없게 되는 문제가 발생

 

Phantom read란?

데이터베이스 트랜잭션 격리 수준 중 하나인 "Repeatable Read" 수준에서 발생할 수 있는 현상

한 트랜잭션 안에서 일정범위의 레코드를 두번 이상 읽을 때, 첫 번째 쿼리에서 없던 유령 레코드가 두번째 쿼리에서 나타나는 현상

 

Repeatable Read 격리 수준에서는 하나의 트랜잭션 내에서 같은 쿼리를 여러 번 실행하더라도 항상 같은 결과를 보장해야 한다.

Phantom read는 이러한 보장을 어기는 현상

 

예시

(1) 트랜잭션 A가 실행된다.
(2) 트랜잭션 A는 SELECT * FROM Orders WHERE Status = 'Pending'과 같은 쿼리를 실행하여 미처리 주문을 가져온다.
(3) 트랜잭션 B가 실행된다.
(4) 트랜잭션 B는 UPDATE Orders SET Status = 'Processed' WHERE Status = 'Pending'과 같은 쿼리를 실행하여 미처리 주문을 처리로 표시한다.
(5) 트랜잭션 A가 다시 실행된다.
(6) 트랜잭션 B에 의해 기존에 미처리된 주문이 처리로 표시되어, 트랜잭션 A를 처음 실행했을 때와 다른 결과를 얻게 된다.

 

일반적으로는 MYSQL InnoDB의 기본 값인 REPEATABLE_READ를 많이 활용한다.

 

Durability(지속성)

commit을 하게 되면 지속(저장)이 꼭 된다.

DB 저장이 실패하더라도 모든 로그를 모두 남겨서 DB에 순차적으로 모두 반영이 되도록 한다.