2 minute read

Mention : 트랜잭션은 나를 너무 편하게 해주고 있었지만, 사실은 생각해야할 것이 많았다🧐

트랜잭션 (Transaction)

  • 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것
    • 거래가 일어날 때의 과정
      • 구매자 계좌에서 10,000원 출금
      • 판매자 계좌에서 10,000원 입금
      • UPDATE 문 : 구매자 계좌에서 10,000원 빼기 → 만약 오류가 발생한다면?
      • UPDATE 문 : 구매자 계좌에서 10,000원 더하기
    • 하나의 트랜잭션은 커밋 혹은 롤백된다.
      • 커밋 - 트랜잭션으로 묶인 모든 쿼리가 성공 → 결과를 DB에 반영
      • 롤백 - 오류발생시 →쿼리실행 결과를 취소하고 → DB를 이전으로 되돌림
  • 트랜잭션 범위는 커넥션 기준
    • 문제가 발생했을 때 롤백해야 하는 범위
  • 트랜잭션 전파
    • 여러 메서드 호출이 한 트랜잭션에 묶이도록 하기 위해 필요
    • ex) 스프링 프레임워크의 트랜잭션 처리 @Transactional
  • 외부 연동이 섞여 있으면 롤백 처리에 주의
    • 외부 시스템은 롤백이 안되는 경우

ACID

  • 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질
  • A (Atomicity, 원자성)
    • all or nothing
    • 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다.
    • 완료되지 않은 트랙잭션의 중간 상태를 DB에 반영해서는 안된다.
  • C (Consistency, 일관성)
    • 트랜잭션 작업처리결과는 항상 일관성 있어야 한다.
    • 데이터베이스는 항상 일관된 상태로 유지되어야 한다.
  • I (Isolation, 독립성)
    • 둘 이상의 트랜잭션이 동시 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다.
    • 각각의 트랜잭션은 서로 간섭없이 독립적으로 이루어져야 한다.
  • D (Durability, 지속성)
    • 트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야한다.

트랜잭션의 성질

  • 성능의 문제 → ex) 동시성 문제
  • 경쟁상태 (Race Condition)
    • 여러 클라이언트가 같은 데이터에 접근할 때 문제 발생
  • 트랜잭션 격리 수준
    • 동시에 DB에 접근할 때 그 접근을 어떻게 제어할지에 대한 설정
      • 다음은 격리 수준을 나타낸 것이다.
      • READ-UNCOMMITTED < READ-COMMITTED < REPEATABLE-READ < SERIALIZABLE
      • 격리수준이 높을수록 데이터 정합성이 높으며, 성능(처리량)은 떨어진다.
      • 격리수준이 낮을수록 동시성에 대한 성능(처리량)은 좋아진다.
      • 데이터 정합성과 성능은 반비례
  • READ-UNCOMMITED
    • 커밋 전의 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 읽는 것 허용
    • Dirty , Non-Reapeatable, Phantom Read 현상이 나타날 수 있다.
  • READ-COMMITED
    • 커밋된 데이터만 읽기
      • 커밋된 값과 트랜잭션 진행 중인 값을 따로 보관
    • 커밋된 데이터만 덮어쓰기
      • 행 단위 잠금 사용
        • 같은 데이터를 수정한 트랜잭션이 끝날 때까지 대기
    • 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능
    • Non-Reapeatable, Phantom Read 현상이 나타날 수 있다.
  • REPEATABLE-READ
    • 트랜잭션 동안 같은 데이터를 읽게 함
      • ex) MVCC (Multi-Version Concurrency Control)
      • 읽는 시점에 특정 버전에 해당하는 데이터만 읽음
    • 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장
    • Phantom Read 현상이 나타날 수 있다.
  • SERIALIZABLE
    • 한 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근 불가
    • 성능이슈 때문에 인덱스 잠금이나 조건 기반 잠금 등을 사용한다.

Problem

  • Dirty read
    • 커밋되지 않은 데이터 읽기
  • Dirty write
    • 커밋되지 않은 데이터 덮어쓰기
  • Read skew
    • 읽는 시점에 따라 데이터가 바뀜
  • Lost Update
    • 변경 유실, 같은 데이터를 쓸 때 발생
    • ex). count, 위키 페이지 수정

Lost Update 해결방안

  • 원자적 연산
    • DB가 지원하는 원자적 연산 사용
      • 동시 수정 요청에 대해 DB가 순차 처리
  • 명시적 잠금
    • 조회할 때 수정할 행을 미리 잠금
    • ex) select…for update
  • CAS (Compare at set)
    • 수정할 때 값이 같은지 비교

트랜잭션 전파 타입

  • 트랜잭션의 경계에서 트랜잭션이 어떻게 동작할 것인가
  • 데이터의 안전성에 관한 문제

Summary

  • 트랜잭션이란 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것 입니다. 트랜잭션으로 쿼리가 묶여있지 않다면, 오류가 발생할 경우 잘못된 결과를 초래할 수 있습니다.
  • 하나의 트랜잭션은 커밋 또는 오류가 있을경우 롤백됩니다.
  • ACID는 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질입니다.
  • 원자는 물질의 최소단위입니다. 따라서 쪼개질수가 없습니다. 따라서 원자성이란, 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다는 것입니다.
  • 일관성은 트랜잭션 작업처리결과와 데이터베이스는 항상 일관성있어야 한다는 것입니다.
  • 독립성이란 둘 이상의 트랜잭션이 동시 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다는 것입니다.
  • 지속성은 트랜잭션이 성공적으로 완료되면 결과는 영구히 반영되어야 한다는 것 입니다.
  • 잠금 시간은 최소화, 잠금 시간이 길어지면 성능(처리량) 저하
  • 동시성 문제를 다룰 때는 사용하는 DB의 기본 격리 레벨 숙지

Reference 📚

https://www.youtube.com/watch?v=e9PC0sroCzc

https://www.youtube.com/watch?v=urpF7jwVNWs&t=297s

Leave a comment