All Articles

[DB] 트랜잭션과 격리수준

트랜잭션

  • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
  • SELECT / INSERT / DELETE / UPDATE 를 통해 데이터베이스에 접근하는 것

    ⇒ 질의어 한 문장이 아니라, 명령문들이 합쳐진 작업의 단위

트랜잭션의 특징 < ACID >

원자성 (Atomicity)

트랜잭션이 데이터베이스에 모두 반영되거나 모두 반영되지 않아야 함

일관성 (Consistency)

트랜잭션의 작업 처리결과가 항상 일관성이 있어야 함

미리 정의된 규칙에서만 수정이 가능

e.g. 송금 전 후 잔액의 데이터 타입은 모두 정수열이어야 한다 ⇒ 일관성

고립성 (Isolation)

트랜잭션 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것

하나의 트랜잭션이 완료될 때까지 다른 트랜잭션이 그 트랜잭션의 결과를 참조할 수 없다

지속성 (Durability)

성공적으로 수행된 트랜잭션은 영원히 반영되어야 함

완전히 반영되면 로그를 남기고, 그 로그를 이용하여 수행 전 상태로 되돌릴 수 있어야 한다

Commit & Rollback

Commit

모든 작업들을 정상적으로 처리했다고 확정하는 명령어

하나의 트랜잭션이 끝났다는 것을 알려주기 위해 사용한다

하나의 트랜잭션을 종료 후, 로그에 저장

Rollback

하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진 경우 처음부터 다시 시작하거나 부분적으로 취소시킨다

트랜잭션의 격리 수준

  • 동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회한 데이터를 볼 수 있는 허용 여부를 결정하는 것

격리 수준의 필요성

  • 트랜잭션이 원자적이면서 독립적 수행이 필요
  • 무조건적인 Locking으로 다른 트랜잭션의 관여를 막는다면, 동시에 수행되는 많은 트랜잭션을 순서대로 처리 ⇒ 성능 저하
  • Locking을 줄여 응답성을 높이려 하면, 잘못된 값이 처리될 여지

격리 수준의 종류

READ UNCOMMITTED

  • 트랜잭션의 변경사항을 Commit 여부에 상관없이 다른 트랜잭션이 읽을 수 있음
  • Dirty Read 현상: 트랜잭션의 작업이 완료되지 않았는데 다른 트랜잭션에서 볼 수 있는 현상

READ COMMITTED

  • 대부분 기본적으로 사용되는 격리 수준
  • Dirty Read 예방 가능
  • 실제 테이블 값이 아니라 Undo 영역에 백업된 값을 가져옴
  • Non-Repeatable Read 문제: 트랜잭션2 가 트랜잭션 1의 값 읽음 ⇒ 트랜잭션 1 커밋 ⇒ 트랜잭션2가 트랜잭션 1의 값 읽음

    • 한 트랜잭션 내에서 똑같은 SELECT 쿼리를 실행했을 때 값이 바뀜
    • Repeatable Read 의 정합성에 어긋남

REPEATABLE READ

  • 트랜잭션이 시작되고 종료되기 전까지 한 번 조회한 값은 계속 같은 값으로 조회
  • 시작 전 커밋된 내용에 한해서만 조회
  • 데이터 변경 시 Undo 영역에 백업해두고 실제 레코드 변경
  • Phantom Read 문제

    • 한 트랜잭션에서 같은 쿼리를 두 번 수행할 때 첫번째 쿼리에 없던 행이 추가되어 새로 입력된 데이터를 읽거나 / 이전에 존재하던 행이 사라지는 것
    • 데이터를 변경시키지 못할 뿐 새로운 데이터를 추가/삭제하는 것은 가능하기 때문에 발생

SERIALIZABLE

  • 트랜잭션이 수행중일 때 INSERT / DELETE 까지 막는 것
  • 강력한 격리수준, 정합성이 보장되지만 동시 처리 성능이 떨어진다