[TIL] Transaction

Manta·7일 전
0

TIL

목록 보기
16/19

Transaction 이란?

컴퓨터 과학 분야에서의 트랜잭션(Transaction)은 "더이상 분할이 불가능한 업무처리의 단위"를 의미합니다.
하나의 작업을 위해서 더이상 분할될 수 없는 명령들의 모음, 즉, 한꺼번에 수행되어야 할 일련의 연산모음을 의미합니다.

사용 예시

  1. 계좌이체를 진행 할때 A에서 B로 송금을 합니다.

  2. A에서 금액이 인출이 되고 B로 차감된 금액만큼 입금 됩니다.

  3. 하지만 여기서 인출은 성공이 됬지만 입금에 실패한다면 치명적인 결과가 나오게 됩니다.

  4. 이 문제를 해결 하기 위해서 "두 과정을 동시에 성공하던지 동시에 실패" 를 하도록 만들어야 합니다.
    이과정을 하나로 묶는 방법이 트랜잭션 입니다.

트랜잭션 격리 수준은 어떤게 있을까?

1. Read Uncommitted

  1. 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관 없이 다른 트랜잭션에서 값을 읽을 수 있습니다.

  2. 정합성에 문제가 많은 격리 수준이기 때문에 사용하지 않는 것을 권장합니다.

  3. 데이터가 Commit이 되지 않는 상태지만 Update된 값을 다른 트랜잭션에서 읽을 수 있습니다.

그렇다면 READ UNCOMMITTED는 문제가 없을까?

💥DIRTY READ현상 발생
트랜잭션이 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있게 되는 현상

2. Read Committed

  1. RDB에서 대부분 기본적으로 사용되고 있는 격리 수준입니다.

  2. Dirty Read와 같은 현상은 발생하지 않습니다.

  3. 실제 테이블 값을 가져오는 것이 아니라 Undo 영역에 백업된 레코드에서 값을 가져옵니다.

그렇다면 READ COMMITTED는 문제가 없을까?

💥 트랜잭션-1이 Commit한 이후 아직 끝나지 않는 트랜잭션-2가 다시 테이블 값을 읽으면 값이 변경됨을 알 수 있습니다.

  • 하나의 트랜잭션내에서 똑같은 SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋납니다.

  • 이러한 문제는 주로 입금, 출금 처리가 진행되는 금전적인 처리에서 주로 발생합니다.

    • 데이터의 정합성은 깨지고, 버그는 찾기 어려워 집니다.

3. Repeatable Read

  1. MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 됩니다.

  2. Undo 공간에 백업해두고 실제 레코드 값을 변경합니다.

  3. 백업된 데이터는 불필요하다고 판단하는 시점에 주기적으로 삭제합니다.

  4. Undo에 백업된 레코드가 많아지면 MySQL 서버의 처리 성능이 떨어질 수 있습니다.

  5. 이러한 변경방식은 MVCC(Multi Version Concurrency Control) 라고 부릅니다.

그렇다면 REPEATABLE READ는 문제가 없을까?

💥PHANTOM READ

  • 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안 보였다가 하는 현상

  • 이를 방지하기 위해서는 쓰기 잠금을 걸어야 합니다.

4. Serializable Read

  1. 가장 단순한 격리 수준이지만 가장 엄격한 격리 수준입니다.

  2. 성능 측면에서는 동시 처리성능이 가장 낮습니다.

  3. SERIALIZABLE에서는 PHANTOM READ가 발생하지 않습니다.
    하지만.. 데이터베이스에서 거의 사용되지 않습니다.

주문이 동시에 들어 왔을때 발생할 수 있는 문제점

<상황 설명>

  1. 유저 A와 B가 같은 메뉴로 동시에 1개씩 주문이 들어 옵니다.

  2. 주문이 들어 왔을때 해당하는 메뉴의 재고를 확인 합니다.

  3. 하지만 남은 재고가 1개 밖에 없습니다.

  4. 재고가 남았기때문에 두 유저 모두 다음단계로 넘어 갑니다.

  5. 이때 문제가 발생합니다.
    두 유저가 동시에 재고를 변경하기 위해 동일한 데이터에 접근을 하게 됩니다.
    이때 일관성 문제가 발생 합니다.

<발생하는 문제점>

  • 경쟁 조건 (Race Condition):
    두 개 이상의 트랜잭션이 동시에 동일한 데이터에 접근하여 변경하려 할 때 발생합니다. 예를 들어, 두 주문이 동시에 동일한 재고를 소진하려고 하면 재고 수치가 올바르게 업데이트되지 않을 수 있습니다.

  • 데드락 (Deadlock):
    두 개 이상의 트랜잭션이 서로가 점유하고 있는 자원을 기다리며 무한히 대기하는 상황입니다. 이로 인해 시스템이 멈출 수 있습니다.

  • 일관성 문제 (Consistency Issues):
    트랜잭션이 동시에 실행되면 데이터베이스의 일관성이 깨질 수 있습니다. 예를 들어, 하나의 주문이 완료되기 전에 다른 주문이 동일한 데이터에 접근하여 잘못된 결과를 초래할 수 있습니다.

<해결 방안>

  1. 킹 메커니즘 (Locking Mechanisms):

    • 비관적 락 (Pessimistic Locking): 자원에 접근하기 전에 락을 걸어 다른 트랜잭션이 접근하지 못하도록 합니다.

    • 낙관적 락 (Optimistic Locking): 트랜잭션이 완료될 때 데이터의 버전이나 타임스탬프를 확인하여 충돌이 발생했는지 체크합니다.

  2. 트랜잭션 격리 수준 (Transaction Isolation Levels):

    데이터베이스의 격리 수준을 조정하여 동시성 문제를 완화합니다.
    예를 들어, "Serializable" 수준을 사용하면 트랜잭션이 순차적으로 실행되는 것처럼 동작하게 됩니다.

  3. 큐잉 시스템 (Queuing Systems):

    주문을 처리하기 전에 큐에 넣어 순차적으로 처리함으로써 동시 접근을 피할 수 있습니다.

  4. 데드락 회피 (Deadlock Avoidance):

    트랜잭션의 순서를 정하거나 자원 요청 순서를 관리하여 데드락이 발생하지 않도록 합니다.
    예를 들어, 모든 트랜잭션이 동일한 순서로 자원에 접근하도록 유도할 수 있습니다.

  5. 비동기 처리 (Asynchronous Processing):

    주문 처리 시스템을 비동기로 설계하여 충돌을 줄이고, 결과를 나중에 업데이트하도록 합니다.

profile
공부할게 너무 만타🫠

0개의 댓글