Computer Science/데이터베이스

DB트랜잭션의 격리 수준(isolation Level)

길순이 2021. 4. 7. 01:20

ACID란?

ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어

 

  • 원자성(Atomicity)은 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.
  • 일관성(Consistency)은 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다. 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.
  • 독립성(Isolation)은 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다. 자세한 내용은 관련 문서를 참조해야 한다.
  • 지속성(Durability)은 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.

Transaction Isolation Level

ACID의 원칙을 너무 타이트하기 지키면 동시성(Concurrency)에 대한 퍼포먼스가 너무 떨어지기 때문에 Isolation Level별로 차등을 두어 동시성에 대한 이점을 가질 수 있게 하지만 아무래도 문제가 발생할 가능성이 있습니다.

이와 연관되어 데이터베이스에서 데이터를 읽은 다음 애플리케이션에서 처리 후 다시 쓰는 경우에 주의가 필요한데 왜 그런지 정리해봅니다.

 

ANSI/ISO SQL Standard 에서 정의한 Isolation Level은 다음과 같습니다.

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

READ UNCOMMITTED

SELECT 쿼리 실행시에 다른 트랜잭션에서 COMMIT 되지 않은 데이터를 읽어올 수 있습니다.
COMMIT 되지 않은 데이터를 읽는 현상을 Dirty read라고 말합니다.
INSERT만 진행되고 ROLLBACK 될 수도 있는, 즉 한번도 COMMIT 되지 않은 데이터를 읽을 수 있어 유의해야합니다.

 

READ COMMITTED

Read Committed에서는 COMMIT이 완료된 데이터만 SELECT시에 보이는 수준을 보장하는 Level이며 대부분의 DBMS에서 Read Committed를 기본으로 설정합니다.

Read Committed에서는 Read Uncommitted에서 발생하는 Dirty read가 발생하지 않도록 보장해줍니다.

트랜잭션에서 COMMIT을 수행하지 않더라도 DB에 이미 값이 반영이 되어있는 상태인데 COMMIT이전의 데이터를 보장 받기 위해서는 COMMIT 되지 않은 쿼리를 복구하는 과정이 필요하게 됩니다.
즉, 이 시점에서는 Consistent Read를 수행해야 함을 의미합니다.

Read Committed의 문제는 하나의 트랜잭션 안에서 SELECT를 수행 할 때마다 데이터가 동일하다는 보장을 해주지 않습니다. 그 이유는 다른 트랜젝션에서 해당 데이터를 COMMIT 했을 경우에는 COMMIT된 데이터를 반환해주는게 Read Committed의 특징이기 때문입니다.
위와 같은 이유로 Read Committed를 Non-repeatable Read 라고도 합니다.

 

REPEATABLE READ

Read Committed와는 다르게 Repeatable Read는 한 트랜잭션 안에서 반복해서 SELECT를 수행하더라도 읽어 들이는 값이 변화하지 않음을 보장합니다.

Repeatable Read 트랜잭션은 처음으로 SELECT을 수행한 시간을 기록한 뒤 그 이후에는 모든 SELECT 마다 해당 시점을 기준으로 Consistent Read를 수행하여줍니다.
그러므로 트랜잭션 도중 다른 트랜잭션이 COMMIT 되더라도 새로이 COMMIT 된 데이터는 보이지 않게됩니다.
그 이유는 첫 SELECT 시에 생성된 SNAPSHOT을 읽기 때문입니다.

해당하는 Row를 INSERT하는 것은 가능합니다. 따라서 동일 트랜잭션에서 Read되는 데이터 수가 달라질 수 있습니다.

SERIALIZABLE

Serializable은 모든 작업을 하나의 트랜젝션에서 처리하는 것과 같은 가장 높은 고립수준을 제공합니다.

Read Committed, Repeatable Read 두개의 공통적인 이슈는 Phantom Read가 발생한다는 점입니다.

 

Transaction Isolation Level 은 Read Uncommited 에서 Serializable  순으로 Concurrency 는 높아지고 속도는 느려진다. 따라서 이 둘의 균형을 잘 맞추는 것이 중요합니다.

위 네가지 Isolation Level  에 따라 나타나는 현상이 세가지가 있습니다.

  • Dirty Read
  • Repeatable Read
  • Phantom Read

Dirty Read

 어떤 트랜잭션에서 아직 실행이 끝난지 않은 다른 트랜잭션에 의한 변경 사항을 보게 되는 되는 경우를 dirty read 라고 합니다. 만약 원래 트랜잭션에서 그 변경 사항을 롤백하면 그 데이터를 읽은 트랜잭션은 dirty 데이터를 가지고 있다고 말합니다.

Repeatable Read

 어떤 트랜잭션에서 같은 질의를 사용했을 때 질의를 아무리 여러번 해도 그리고 다른 트랜잭션에서 아무리 여러 번 그 행을 변경해도 항상 같은 데이터만 읽어드리는 경우를 repeatable read 라고 합니다. 즉 repeatable read 가 요구되는 트랜잭션에서는 다른 트랜잭션에 의한 변경 사항을 볼 수가 없습니다. 그러한 변경 사항을 보고 싶으면 어플리케이션에서 트랜잭션을 새로 시작해야 합니다.

Phantom Read

 phantom read 는 다른 트랜잭션에 의한 변경 사항으로 인해 현재 사용 중인 트랜잭션의 WHERE 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것입니다. 예를 들어, 잔고가 $100 미만인 계좌를 모두 찾아내는 트랜잭션이 있고, 이 트랜잭션에서 그 데이터를 두 번 읽는다고 가정합시다. 처음 데이터를 읽어들이고 난 후에 다른 트랜잭션에서 잔고가 $0인 계좌를 새로 만들면 이 계좌도 잔고가 $100 이하라는 조건에 맞게 됩니다. 트랜잭션 격리 수준(Transaction Isolation Level)에서 phantom read 를 지원하면 새로운 “유령(phantom)”행이 나오지만 지원하지 않으면 새로 생긴 행을 볼 수 없습니다.

 

결론 : SERIALIZABLE이 아니면 UPDATE, DELETE에 주의

참고 : ko.wikipedia.org/wiki/ACID

velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-

blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/

suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/

 

Lock으로 이해하는 Transaction의 Isolation Level

개요 내게 transaction의 isolation level은 개발할 때 항상 큰 찝찝함을 남기게 하는 요소였다. row를 읽기만 할 때는 REPEATABLE READ로, row를 삽입 / 수정 / 삭제할 때는 SERIALIZABLE로 isolation level을 지정했지

suhwan.dev

 

SQL 트랜잭션 - 믿는 도끼에 발등 찍힌다

RDBMS를 쓰는 이유 중 하나는 트랜잭션입니다. 하지만 RDBMS의 트랜잭션을 너무 믿다가는 깜짝 놀랄 일이 벌어질 수도 있습니다.

blog.sapzil.org

 

Transaction Isolation Level 정리

Isolation을 알기전에 먼저 트랜잭션이 중요시 여기는 ACID라는 것을 먼저 알아야 합니다.Atomicity, Consistency, Isolation, Durability의 앞글자를 따서 ACID라고 불리웁니다.하나의 트랜잭션이 작업이 그중에

velog.io

 

ACID - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 다른 뜻에 대해서는 애시드 문서를 참조하십시오. ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한

ko.wikipedia.org