Transaction

  • CS에서 트랜잭션은 더이상 쪼갤수없는 가장작은 엄무처리 단위
  • DB에서 트랜잭션은 여러 SQL문을 하나의 작업(Operation)으로 실행될 수록 있도록 하는 논리적 작업 단위데이터의 정합성을 보장한다.

    즉, 트랜잭션은 데이터베이스의 상태를 변화시키는 작업을 하나의 논리적 단위로 묶은 것이다.

트랜잭션 사용시 주의점

  • 트랜잭션 사용시 범위를 최소화 해야한다.
  • 비즈니스 로직의 시작이 아닌, DBMS에 데이터를 저장(변경)하는 시점에 트랜잭션을 시작하는것이 좋다
  • 연산이 길어지면 lock을 잡는 시간도 길어지고 최악의 경우엔 DB 커넥션 풀이 고갈될 수 있다

트랜잭션의 성질(ACID)

1. 원자성(Atomicity)

  • 트랜잭션은 All or nothing로, 연산이 중간에 중단되지 않는 것을 보장한다
  • 이는 논리적인 작업 셋을 완벽하게 처리하거나 처리하지 못할 경우에는 원상태로 복구해서 적용되는 현상이 없도록 한다
  • MySQL에서는 MVCC의 `undo log`를 이용하여 트랜잭션의 원자성을 보장

MVCC란?

하나의 레코드에 대해 여러 버전을 관리하여 격리 수준에 따라 반환데이터를 달라지도록 하는 기능

2. 일관성(Consistency)

  • 트랜잭션이 성공적으로 종료(완료)되었을 때는 데이터의 무결성을 보장해야한다( = 데이터베이스는 여전히 일관된 상태여야 한다)
  • MySQL에서는 제약조건을 통해 일관성을 유지
    ➔ 따라서 MySQL은 트랜잭션 격리수준 설정을 통해 여러 트랜잭션간의 작업 내용을 어떻게 공유하고 차단할지를 설정한다

3. 격리성,독립성(Isolation)

  • 둘 이상의 트랜잭션이 동시에 실행되는경우, 하나의 트랜잭션이 실행중이라면 실행 중인 트랜잭션의 중간결과에 다른 트랜잭션의 연산이 접근할 수 없고 수행중인 트랜잭션이 완전히 완료되어야 접근할 수 있다
  • 여러 트랜잭션이 실행중이어도 각각의 트랜잭션은 서로 간섭하지 않고 독립적으로 실행되어야한다
  • 독립성을 보장하기위해서는 각각의 트랜잭션이 순차적으로 실행되어야 하는데, 이는 동시성 성능 저하의 문제를 일으킨다

  • 트랜잭션 격리 수준 (Isolation Level)

    격리 수준 설명
    READ UNCOMMITTED - 커밋되지 않은 데이터도 읽을 수 있음
    - Dirty Read 문제가 발생할 수 있음 (다른 트랜잭션 롤백 시 문제)
    READ COMMITTED - 커밋된 데이터만 읽을 수 있음
    - Dirty Read는 막지만, Non-Repeatable Read는 발생할 수 있음
    REPEATABLE READ - 트랜잭션이 시작될 때 읽은 데이터는 끝날 때까지 변하지 않음
    - Non-Repeatable Read 방지
    - Phantom Read는 발생할 수 있음
    SERIALIZABLE - 모든 문제(Dirty, Non-Repeatable, Phantom Read) 방지
    - 동시성 처리 성능이 급격히 떨어짐 (거의 순차 실행)
  • 📌 트랜잭션에서 발생 가능한 문제점

    문제 설명
    Dirty Read 다른 트랜잭션에서 커밋되지 않은 데이터를 읽음
    Non-Repeatable Read 같은 쿼리를 두 번 실행했는데 읽은 결과가 다름 (다른 트랜잭션이 수정했기 때문)
    Phantom Read 같은 조건으로 조회했는데 추가/삭제된 데이터 때문에 결과가 달라짐

4. 영속성(Durability)

  • 트랜잭션이 성공적으로 완료되면 그 결과는 유실되지 않고 DB에 영구적으로 반영되어야된다 MySQL은 redo log를 통해 트랜잭션의 영속성을 보장한다.

트랜잭션의 연산

1. Commit

  • 하나의 논리적 단위(트랜잭션)에 대한 작업이 성공적으로 끝났고 데이터베이스가 다시 일관된 상태에 있을 때, 이 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산
  • 트랜잭션 작업이 모두 성공했음을 확정하고, 변경 사항을 데이터베이스에 반영하는 연산

2. Rollback

  • 하나의 트랜잭션 처리가 비정상적으로 종료되어 일관성을 깨뜨렸을때, 트랜잭션의 일부가 정상적으로 처리되었더라도 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산
  • 트랜잭션 중 오류 발생 시, 모든 변경 사항을 취소하여 데이터베이스를 원래 상태로 되돌리는 연산
  • Rollback시 해당 트랜잭션을 재시작하거나 폐기한다

3. Savepoint

DB에서는 SAVEPOINT를 이용해 트랜잭션 중간에도 부분 롤백이 가능하다

  • 트랜잭션 내에 저장점을 설정하는 기능
  • 저장점까지는 작업을 유지하고, 그 이후만 Rollback 가능
  • 긴 트랜잭션을 더 세밀하게 제어할 수 있게 해줌

    SAVEPOINT savepoint_name; -- 저장점 설정
    ROLLBACK TO savepoint_name; -- 특정 저장점으로 롤백
    

    4. Lock

  • 트랜잭션이 동시에 실행될 때 데이터 무결성과 일관성을 보장하기 위해 Lock을 사용한다
  • Lock을 사용하여 동시성(Concurrency) 과 데이터 정합성(Consistency) 사이의 균형을 맞출 수 있다

  • 종류

    종류 설명
    공유 락
    (Shared Lock, S-lock)
    - 데이터를 읽을 때 걸리는 락. 여러 트랜잭션이 동시에 읽을 수 있지만, 수정은 불가능
    - 다수의 트랜잭션이 동시에 접근 가능하지만, 배타락은 단독 접근만 허용
    배타 락
    (Exclusive Lock, X-lock)
    - 데이터를 수정할 때 걸리는 락. 다른 트랜잭션은 읽기도, 쓰기도 불가능
    데드락(Deadlock) - 두 개 이상의 트랜잭션이 서로 락을 점유하고 상대방이 점유한 락을 기다리는 경우 발생(교착상태)
    - DBMS는 데드락 감지(Detection) 및 회복(Recovery) 기능을 통해 데드락을 자동으로 처리

트랜잭션의 상태

상태 설명
활동 (Active) 트랜잭션이 실행 중인 상태
실패 (Failed) 트랜잭션 실행 중 오류가 발생해 중단된 상태
철회 (Aborted) 트랜잭션이 비정상적으로 종료되어 Rollback이 수행된 상태
부분 완료 (Partially Committed) 트랜잭션의 마지막 연산까지 실행했지만, Commit 직전 상태
완료 (Committed) 트랜잭션이 성공적으로 종료되어 Commit이 완료된 상태

댓글남기기