티스토리 뷰

Transaction

  • 여러 읽기/쓰기를 논리적으로 하나로 묶음
    • 트랜잭션 시작 -> 여러 쿼리 실행 -> 커밋 or 롤백
    • 모두 반영(커밋) or 모두 반영 안 하기(롤백)
  • 트랜잭션 범위는 컨넥션 기준
    • 트랜잭션의 모든 쿼리는 같은 커넥션에 있어야 한다.
    • 커넥션이 3개라면 트랜잭션을 가질 수 있다
  • 트랜잭션 전파
    • 여러 메서드 호출이 한 트랜잭션에 묶이도록 하기 위해 필요
      • 스프링 프레임워크: 메서드 간에 커넥션 객체를 전달하지 않아도 한 트랜잭션으로 묶어서 실행
  • 외부 연동 주의
    • 한 트랜잭션에 외부 API 연동이 있을 때 롤백 처리에 주의해야 한다.

경쟁 상태(Race Condition)

여러 트랜잭션이 동시에 같은 레코드에 접근하면 동시성 문제(경쟁 조건) 발생

  • 해결책
    • 트랜잭션을 순서대로 실행
      • 동시성에 대한 문제 원천 차단
      • 한 번에 한 개의 트랜잭션만 처리하기 때문에 성능(처리량) 저하
    • 트랜잭션 격리(Isolation)

Dirty Read(커밋되지 않은 데이터 읽기)

  • 어떤 트랜잭션이 커밋 되지 않은 다른 트랜잭션(혹은 aborted 된)이 쓴 데이터를 읽는 것을 일컫는다
  • A 계좌에서 B 계좌로 100만 원을 송금시킨다고 했을 때 송금 과정 중에 계좌 잔고 조회를 하면 1000이어야 할 금액이 900으로 조회가 될 수 있다.

https://ketanbhatt.com/db-concurrency-defects/

Dirty Write(커밋되지 않은 데이터 덮어쓰기)

  • 어떤 트랜잭션이 커밋되지 않은 다른 트랜잭션(혹은 aborted 된)의 트랜잭션 데이터를 overwrite 하는 것을 일컫는다
  • 방을 빌리는 과정에서 room name과 participant를 변경해준다.
    • Ranyinudo는 room name=Appraisal, participant=Ranyinudo로 변경한다.
    • 동시에 Ginika는 room name=1-1, participant=Ginika로 변경한다.
    • Ginika, Ranyinudo의 트랜잭션이 아래 그림과 같이 실행되면서 되면서 room name=1-1, participant=Ranyinudo의 결과를 갖게 된다.

https://ketanbhatt.com/db-concurrency-defects/

Read Skew(읽는 동안 데이터 변경)

  • 보통 시간 차이로 발생하는 이상 현상
  • Repeatable Read에서 생길 수 있는 현상
  • Dirty Read가 아닌 정상 프로세스로 커밋된 결과로 인해 오래된 버전과 새로운 버전의 데이터를 모두 만나게 되는 경우
  • 2번 계좌에서 1번 계좌로 송금 트랜잭션이 있을 때
    • Alice가 해당 트랜잭션 전에 1번 계좌에서 500을 확인
    • Alice가 해당 트랜잭션 후에 2번 계좌를 확인했을 때 400을 확인하게 되면 100이 사라진 거처럼 느낄 수 있다.

https://nominationp.github.io/2020/03/22/transcations-week-isolation-levels/

Lost Update(갱신 손실)

  • read-modify-write 주기로 작업할 때 발생
  • 동시 쓰기 작업 시 발생하는 쓰기 충돌 중 하나
    • i.e. count증가, 위키 페이지 수정
  • 종종 이와 같은 충돌을 "Last Write Wins"로 해결하기도 한다.

https://nominationp.github.io/2020/03/22/transcations-week-isolation-levels/

해결책

  • 원자적(atomic) 연산
    • DB가 지원하는 원자적 연산 사용
      • 동시 수정 요청에 대해 DB가 순차 처리
    • i.e. UPDATE counters SET value = value + 1 WHERE key = 'foo';
  • 명시적 잠금(exciplit lock)
    • 조회할 때 수정할 행을 미리 잠금
      • i.e. select ... for update
  • CAS(Compare And Set)
    • 각 Row에다가 Version 붙이고, UPDATE 시마다 Version 이 변경하지 않았을 때만 진행하고 그 외에는 재시도
    • Repeatable Read 쓸 때 유의

Write Skew

  • Lost Update문제의 일반화된 문제다
    • concurrent 한 트랜잭션이 같은 객체를 읽고 다른 객체를 업데이트하는 것
    • 같은 객체를 업데이트하면 Lost Update 문제, 다른 객체를 업데이트하면 Write Skew 문제라 할 수 있다.
  • 우버와 같은 서비스에서 Omphile가 가능한 차를 호출(broadcast) 한다.
    • Driver A와 Driver B는 customer가 배차가 안된 거를 확인하고 각각 둘 다 배차를 하게 되는 문제다

https://ketanbhatt.com/db-concurrency-defects/

  • 다른 예시로는 당직 트랜잭션이 있다.
    • 트랜잭션이 처음 시작할 때는 2명이었는데 트랜잭션 종료 후 0명이 된다.
    • 당직 수를 1명으로 유지해야 하는 정책이 깨질 수 있는 버그다.

https://youngminz.netlify.app/posts/data-intensive-application-transaction

Phantom

  • 한 트랜잭션이 다른 트랜잭션의 검색 결과를 바꿔버리는 문제

https://dotnettutorials.net/lesson/phantom-read-concurrency-problem-sql-server/

해결책

  • 빈 결과를 SELECT 한 후에 INSERT를 하는 경우에는 아무것도 잠글 것이 없으므로, 스냅숏 격리로는 안되고 직렬성 격리가 필요

트랜잭션 격리(Transaction Isolation)

트랜잭션을 서로 격리해서 다른 트랜잭션이 영향을 주지 못하게 함

격리 수준(Isolation Level)

         
Isolation Level/Read phenomena Dirty Reads Lost Updates Non-repeatable Reads Phantoms
Read Uncommitted o o o o
Read Committed x o o o
Repeatable Read x x x o
Serializable x x x x

Read uncommitted

  • SELECT 질의 수행 시 해당 데이터에 Shared Lock이 걸리지 않는다.
  • Dirty Read는 있지만 Drity Write는 없다.

Read Committed

  • 대부분의 DBMS에서 사용하는 레벨(MySQL 제외)
  • SELECT 질의 수행시 해당 데이터에 Shared Lock이 걸린다.
  • 커밋된 데이터만 읽기 (Dirty Read 방지)
    • 커밋된 값과 트랜잭션 진행 중인 값을 따로 보관
  • 커밋된 데이터만 덮어쓰기 (Dirty Write 방지)
    • 행 단위 잠금 사용
      • 같은 데이터를 수정한 트랜잭션이 끝날 때까지 대기

Repeatable Read/Snapshot Isolation

  • 트랜잭션 동안 같은 데이터를 읽게 함
    • i.e. MVCC(Multi-Version Concurrency Control)
      • 읽는 시점에 특정 버전에 해당하는 데이터만 읽음

Serializable

  • 트랜잭션이 완료될 때까지 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능
  • 인덱스 잠금이나 조건 기반 잠금 등 사용

ACID

Atomic/Atomicity(원자성)

  • 트랜잭션에 기록한 모든 내용이 성공하거나 모두 취소되는 것을 보장

Consistency(일관성)

  • 데이터가 Correct State [각주:1]라면 트랜잭션을 수행하고 난 Correct State여야 한다.
  • 데이터가 항상 진실인 불변식(invariant)을 만족한다는 보장
    • Application 정책과 관련, ACID 중 유일한 Application의 책임
    • i.e. 회계 프로그램에서 차변과 대변이 항상 같아야 하는 정책

Isolated(격리성)

  • 동시에 실행되는 트랜잭션은 서로 격리된다는 보장
  • 트랜잭션은 다른 트랜잭션을 방해할 수 없다.

Durable(지속성)

  • 데이터베이스가 죽어도 데이터가 손실되지 않는다는 보장
  • 트랜잭션이 커밋됐다면 시스템에 남아있어야 한다.

Reference

  1. 도메인의 유효 범위, 무결성 제약조건 등의 제약 조건을 위배하지 않는 정상적인 상태 [본문으로]
반응형

'CS' 카테고리의 다른 글

[Network] HTTP/0.9 ~ 1.1  (0) 2022.01.03
[Network/OS] Network Socket(IP Socket, WebSocket)  (0) 2021.12.27
Interpreter VS Compiler  (0) 2021.11.26
[Network]기본 개념  (0) 2021.10.30
[Network]Cloud 종류  (0) 2021.10.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함