코딩은 내일부터

트랜잭션과 트랜잭션 격리수준 그게 뭔데. 본문

우아한 테크 코스(우테코)/우테코 공부

트랜잭션과 트랜잭션 격리수준 그게 뭔데.

zl존 비버 2023. 8. 23. 17:03
728x90

트랜잭션이란?

트랜잭션은 꼭 여러개의 변경작업을 수행하는 쿼리가 조합됐을때 의미 있는 개념이 아니다.

작업이 모두 적용되거나 아무것도 적용되지 않아야함을 보장해주는것을 의미한다.

다시 말해 논리적 작업 단위를 트랜잭션이라고 부른다.

 

ACID? 그게 뭔데.

ACID는 트랜잭션의 4가지 특성의 약자들을 모아놓은거다.

 

Atomicity(원자성)

원자성이란 하나의 트랜잭션이 모두 성공하거나, 모두 실패해야하는 성질이다.

말 그대로 작업을 수행하는 도중 하나의 쿼리가 잘못됐을때 그 전에 수행한 쿼리는 모두 반영되지 않고 초기 상태로 돌린다는 뜻이다.

Consistency(일관성)

일관성은 하나의 트랜잭션 이전과 이후, 데이터베이스의 상태는 이전과 같이 유효해야한다는 것이다.

예를 들어 비버 서비스의 회원가입할때 사용자의 이름이 무조건 필요하다고(NotNull) 한다면 트랜잭션이 일어난 이후에도 이름의 제약조건을 만족해야한다는 것이다.

Isolation(격리성, 고립성)

격리성은 모든 트랜잭션은 다른 트랜잭션의로부터 독립되어야한다라는 성질이다.

이 부분은 Durability(영속성)을 알아본 다음에 더 자세히 알아보겠다.

Durability(영속성)

성공적으로 수행된 트랜잭션은 요청된 작업의 내용이 데이터베이스에 영원히 반영되어야 함을 의미한다.

시스템 문제가 발생하더라도 DB에 내용은 기존과 같이 유지되어야한다는 성질이다.

 

이렇게 트랜잭션의 성질 4가지를 알아보냈는데 다음으로는 트랜잭션의 격리수준을 알아보겠다.

 

 

격리수준이란?

앞서 알아본 ACID의 Isolation는 4가지의 격리수준으로 나눠볼 수 있다.

 

  • READ UNCOMMITTED (커밋되지 않은 읽기)
  • READ COMMITTED (커밋된 읽기)
  • REPEATABLE READ (반복 가능한 읽기)
  • SERIALIZABLE (직렬화 가능)

밑으로 갈수로 격리 수준이 높아지며, 동시 처리 성능이 낮아진다.

반대로 위로 갈수록 격리수준이 낮아지고, 동시처리 성능이 높아지지만 데이터 부정합 문제가 발생할 확률이 높아진다.

 

즉, 데이터 정합성과 성능은 반비례한다.

 

 

다음은 각 격리수준에서 발생하는 문제이다. 격리수준과 같이 알아보겠다.

 

 

READ UNCOMMITTED

(DIRTY READ, ON-REPEATABLE READ, PHANTOM READ 발생 가능)

 

READ UNCOMMITTED 는 가장 낮은 격리수준 중 하나로,

말그대로 트랜잭션이 다른 트랜잭션에서 아직 커밋되지 않은 변경사항을 읽을 수 있도록 허용한다.

 

여기서 하나의 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 변경 사항을 읽는 것을 더티 리드(DIRTY READ)라고 하는데

DIRTY READ의 문제점은 A트랜잭션 변경사항이 있었을때 B트랜잭션이 변경사항을 읽을 수 있다.

 

이때 A트랜잭션이 롤백을 하면 두 개의 트랜잭션 간에 데이터의 일관성이 깨질 수 있다라는 문제 점이 발생할 수 있다.

 

READ COMMITTED

(NON-REPEATABLE READ, PHANTOM READ 발생 가능)

 

READ COMMITTED 는 2번째로 가장 낮은 격리수준으로 커밋된 데이터만 읽어오도록 허용한다.

여기서는 dirty read가 발생할 수 없고, 가장 많이 사용하는 격리수준이며, 오라클에서 기본 값으로 설정되어있다.

하지만 NON-REPEATABLE READPHANTOM READ가 발생 할 수 있다.

 

NON-REPEATABLE READ는 같은 트랜잭션 내에서 같은 데이터를 여러번 조회했을 때 읽어온 데이터가 다른 경우를 의미한다.

그림과 같이 보면 A와 B에서 처음 Select하면 name에 비버가 들어있는것을 확인할 수 있다.

여기서 A에서 Ingpyo로 이름을 바꾸면 B에서는 같은 트랜잭션 인데 데이터가를 조회했을때 읽어온 데이터가 다르다(정합성이 깨진다.).

이러한 예시가 NON-REPEATABLE READ라고 한다.

 

NON-REPEATABLE READ는 알겠는데 PHANTOM READ를 찾아보면 다음과같은 뜻이라는 것을 알 수 있다.

Non-Repeatable Read의 한 종류로 조회해온 결과의 행이 새로 생기거나 없어지는 현상이다.

 

둘 다 조회했을때 데이터가 달라질때를 의미하는거 같은데 둘의 차이가 없는거같다.

 

그래서 답을 얻기위해 Real MySQL를 찾아보면

Non-Repeatable Read는 "한 레코드의 값"에 초점이 맞춰져있고, Phantom Read는 "레코드의 존재 유무"에 초점이 맞춰져 있다

라고 나와있다.

 

즉, Non-Repeatable Read는 한 레코드에서 Update문이 날라왔을때 그 하나의 레코드를 조회했을 때 발생하는 문제이고,

Phantom Read는 한 레코드를 Insert,Delete를 했을때 레코드의 집합을 조회할 때 발생하는 문제이다.

 

 

 

REPEATABLE READ

(PHANTOM READ 발생 가능)

Read Committed와 달리 특정 행을 조회했을때 항상 같은 격리수준을 보장해주는 격리 레벨이다.

하지만 NON-REPEATABLE READ는 막을 수 있지만, Phantom Read와 같은 문제는 막을 수없다..

Non-Repeatable Read를 설명한 사진이다.

이 예시에서 Update문이 아닌 Insert문을 날렸다고 가정하면 B트랜잭션에서 select문으로 조회를 해보면

비버와 Ingpyo가 조회되는걸 볼 수 있을 것이다.

 

 

 

SERIALIZABLE

마지막으로 SERIALIZABLE는 특정 트랜잭션이 사용중인 테이블의 모든 행을 다른 트랜잭션이 접근할 수 없도록 잠근다. 가장 높은 데이터 정합성을 갖고 있지만, 성능은 가장 떨어진다.

이 격리 수준에서는 단순한 SELECT 쿼리가 실행되더라도, 데이터베이스 락이 걸려 다른 트랜잭션에서 데이터에 접근할 수 없게된다.

 

 

격리 어렵다..