[Database] 트랜잭션(Transaction), ACID 및 Isolation Level

2023. 2. 25. 06:56
반응형

트랜잭션 (Transaction)

하나의 로직을 처리하는 SQL 질의들을 집합으로 묶어, 도중에 예외가 발생할 경우 Rollback 처리를, 모두 성공할 경우 Commit 처리하는 실행 단위이다.

 

쇼핑몰에서 주문할 때의 과정을 생각해보자. (주문 요청 -> 결제 처리 -> 성공 시 주문 완료 데이터 저장)

만약에 다음 과정에서 결제는 완료되었는데 주문이 들어가지 않았다면 사용자 입장에서는 어이가 없을 것이다.

또 결제 처리는 실패되었는데 주문 완료 데이터는 저장되어있다면 해당 데이터베이스는 더이상 믿을 수 없게 된다.

 

즉, 성공하려면 모두 성공하고, 실패하려면 모두 실패해야 한다.

 

 


트랜잭션 작성 예시 (MySQL)

BEGIN
	START TRANSACTION;	-- 트랜잭션 시작. rollback이나 commit을 만날 때 까지 트랜잭션
		
        -- 일련의 작업 ...
			
		IF 조건 > THEN	-- ROLLBACK
		ROLLBACK;

        -- 일련의 작업 ...
        
	COMMIT;		-- 트랜잭션 성공
END

 

 


Transaction ACID

 

데이터베이스의 트랜잭션에 대해서 데이터의 정확성과 안전성을 보장하고 데이터 오염을 방지하기 위한 성질이다.

 

  • A(Atomicity) : 원자성
    • 트랜잭션의 작업은 모두 성공하거나, 모두 실패하여야 함 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력. 

 

  • C(Consistency) : 일관성
    • 트랜잭션이 실행을 성공적으로 완료될 시 일관적인 DB상태를 유지해야 한다.
    • 트랜잭션이 일어난 이후 자료형, 길이, 관계 등 데이터베이스 규칙이 변하지 않아야 한다.

 

  • I(Isolation) : 격리성
    • 일련의 트랜잭션을 작업 중 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 격리시키는 것
    • 트랜잭션은 다른 트랜잭션으로부터 독립성을 유지되어 있어야 하며, 같은 자원을 사용한다면 동시에 실행될 수 없음
    • 철수의 작업 동안에서는 영희의 작업은 기다려야 함

 

  • D(Durability) : 지속성
    • 트랜잭션에 대한 로그가 남아야 하는 성질로 런타임 오류나 시스템 오류가 발생하더라도, 해당 기록은 영구적이어야 하는 것.
    • commit이 되었으면 런타임 오류로 서버가 재실행 되더라도, 그 데이터는 그대로 유지가 되어야 되는 것.

 

 

 


Isolation Level

ACID의 성질 중 Isolation에는 격리 수준이 존재한다.

동시에 트랜잭션 작업이 이루어질 때, A 트랜잭션에서 B 트랜잭션의 조회중이거나 변경중인 데이터에 대한 접근을 허용할지 말지에 대한 수준을 결정하는 것이다.

 

Isolation Level에는 다음과 같이 네가지의 수준이 있다.

 

Level Dirty-Read Non-Repeatable
Read
Phantom-Read
1 Read-Uncommited O O O
2 Read-Committed X O O
3 Repatable-Read X X O
4 Serializable X X X

 

 

 


Read-Uncommited

 

https://en.wikipedia.org/wiki/Isolation_(database_systems)

  • 다른 Transaction에서 업데이트가 커밋되지 않았더라도 변경된 데이터를 조회할 수 있다.
  • A 트랜잭션에서 사용자 정보를 조회하는 도중, B 트랜잭션에서 사용자 정보가 변경되고 커밋되지 않았더라도 A에서는 커밋되지 않은 변경된 데이터를 조회하게 된다.

 

 


Read-Commited

 

  • Commit되기 이전의 작업은 DB의 Undo 영역에 저장해 둔 후 Commit된 이후 실행되게 된다. (Dirty Read 방지)

https://en.wikipedia.org/wiki/Isolation_(database_systems)

  • 트랜잭션이 시작되기 전에 커밋된 내용만 반영된 데이터에 대해서만 조회할 수 있는 격리 수준이다.
  • 다른 Transaction에서 업데이트가 커밋되지 않았으면 변경된 데이터를 조회할 수 없다.
  • 트랜잭션 도중 다른 트랜잭션에서 업데이트가 커밋되었다면 변경된 데이터를 조회할 수 있다.
  • 커밋된 데이터만 조회할 수 있으나 동일한 쿼리에 대해서 다른 결과가 나올 수 있다. 
  • A 트랜잭션에서 여러번 사용자의 정보를 조회하고 있는 도중, 사용자의 정보를 변경하는 B 트랜잭션이 완료되어 Commit된다면, A에서는 같은 사용자 정보 조회 쿼리이지만 다른 결과가 나올 수 있다.

 

 


Repatable-Read

 

  • 트랜잭션 내에서 조회하는 데이터에 대해 공유락을 걸어 잠금된 데이터의 변경 불가능이 보장된다.
    • 공유락 : 리소스의 WRITE 제한
    • 베타락 : 리소스의 READ/WRITE 제한
  • 이를 위해서 DBMS의 트랜잭션은 트랜잭션 번호를 가지며, 자신보다 낮은 트랜잭션 번호에서 커밋된 내용만을 사용한다. 만약 Update와 같이 A 트랜잭션이 끝나기 이전에 실행되어서는 안되는 내용이 있다면 Undo 영역에 저장해 둔 후 A 트랜잭션이 끝난 이후 실행되게 된다.
  • 관계형 데이터베이스에서는 대부분 해당 격리 수준을 기본으로 사용한다.

 

Update 부정합성

  • 그러나 Update의 부정합성을 일으킬 수 있다. B 트랜잭션의 Update문은 A 트랜잭션이 완료되기 이전까지 Undo영역에 저장되게 된다. 하지만 A 트랜잭션 안에서도 Update문이 있다. 이렇다면 A의 업데이트가 실행되고 Commit된 이후 B의 업데이트가 실행되게 되어 결국 age는 21이 되는 부정합성이 일어나게 된다.

 

 

Phantom Read

https://en.wikipedia.org/wiki/Isolation_(database_systems)

  • Repetable-Read는 트랜잭션 내에서 공유 잠금된 데이터의 Update 불가능이 보장된다. 그렇지만...
  • A 트랜잭션에서 여러번의 조회 실행 중, B 트랜잭션 Insert이 된 후 테이블을 Select하면 없었던 B에서 Insert된 유령 데이터(Phantom Read)가 나타날 수 있다.
  • Phantom Read : 트랜잭션 도중 다른 트랜잭션에서 Insert되거나 Delete가 발생하면, 트랜잭션 안에서 데이터가 추가되거나 삭제된 채로 조회되는 현상이 나타난다.
  • 트랜잭션 도중 다른 트랜잭션에서 행 추가가 커밋되었다면 추가된 데이터를 조회할 수 있다.
  • A 트랜잭션에서 여러번 사용자의 정보를 조회하고 있는 도중, 사용자를 추가하는 B 트랜잭션이 완료되어 Commit된다면, A에서는 같은 사용자 조회 쿼리이지만 추가된 행이 포함되어 다른 결과가 나올 수 있다.

 


Serializable

 

  • 트랜잭션 내에서의 Select된 자원들은 공유 잠금된다.
  • 트랜잭션 내에서 공유 잠금된 데이터의 수정 및 입력 불가능이 보장된다. 
  • Phantom Read가 발생하지 않는다.
  • 가장 단순하면서 가장 엄격한 관리 수준이다.
  • 성능 측면에서는 동시 처리 성능이 가장 낮다.

 

 


격리 수준의 선택

 

위에서 살펴보았을 때 그러면 무조건 격리 수준을 높이면 되는 것이 아닌가? 할 수도 있겠지만 격리 수준과 성능은 반비례하게된다.

따라서 일반적인 웹 어플리케이션의 비즈니스 로직들은 Read-Commited 수준으로 사용하는 경우가 많으나 금전적인 처리 등 예민한 데이터를 다룰 때에는 격리 수준을 높여야 한다.

 

 

아래와 같은 타임라인을 살펴보자

 

A B C의 잔액
A가 C에게 1000원 계좌이체 요청   0
  B가 C에게 2000원 계좌이체 요청 0
C의 잔액 계산 : C의 잔액(0) + 1000   0
... 처리중 C의 잔액 계산 : C의 잔액(0) + 2000 0
송금 완료, C의 잔액 = C의 잔액(0) + 1000 ... 처리중 1000
  송금 완료, C의 잔액 = C의 잔액(0) + 2000 2000

 

A와 B가 C에게 송금을 할 때 격리수준이 낮으면 다음과 같은 현상이 발생하게 된다.

따라서 민감하고 엄격한 데이터일수록 Transaction의 격리 수준을 높이고, 그렇지 않은 일반적인 데이터는 격리 수준을 완화시키는 것이 좋다.

 

 

 

 

 

 

 

 


Reference

https://joont92.github.io/db/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80-isolation-level/

 

[db] 트랜잭션 격리 수준(isolation level)

트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. 즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에

joont92.github.io

https://en.wikipedia.org/wiki/Isolation_(database_systems) 

 

Isolation (database systems) - Wikipedia

From Wikipedia, the free encyclopedia In database systems, isolation determines how transaction integrity is visible to other users and systems. A lower isolation level increases the ability of many users to access the same data at the same time, but incre

en.wikipedia.org

https://victorydntmd.tistory.com/129

 

[DB이론] 트랜잭션(transaction)과 ACID 특성을 보장하는 방법

1. 트랜잭션( transaction )트랜잭션이란 질의(query)를 하나의 묶음 처리해서 만약 중간에 실행이 중단됐을 경우,처음부터 다시 실행하는 Rollback을 수행하고, 오류없이 실행을 마치면 commit을 하는 실

victorydntmd.tistory.com

 

반응형

BELATED ARTICLES

more