ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Transaction: ACID, 격리 수준, 락, 전파 옵션
    Spring 2025. 8. 12. 20:41

    트랜잭션 ACID

    1. 원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나 실패해야 된다.
    2. 일관성(Consistency): 트랜잭션 이전과 이후에는 항상 consistent 상태여야 한다.
    3. 격리성(Isolation): 동시에 실행되는 트랜잭션들이 다른 트랜잭션에 영향을 주어서는 안된다.
    4. 지속성(Durability): 트랜잭션이 성공적으로 끝내면 그 결과가 항상 기록되어야 한다.

    트랜잭션 격리수준

    트랜잭션의 격리 수준(Isolation Level)이란 여러 트랜잭션이 동시에 실행될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 여부를 결정하는 것

    상호작용

    • Dirty Read: 아직 커밋되지 않은 다른 트랜잭션의 데이터를 읽는 것을 의미
    • Non-repeatable Read: 다른 트랜잭션이 커밋한 데이터를 읽는 것을 의미
    • Phantom Read: 다른 트랜잭션이 커밋한 데이터가 있더라도 자신의 트랜잭션에서 읽었던 내용만 사용하는 것을 의미

    Isolation Level 종류

    • Read Uncommitted
    • Read Committed
    • Repeatable Read
    • Serializable

    Read UnCommitted

    • commit이나 rollback에 상관없이 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 읽는 것을 허용하는 트랜잭션 격리 수준
    • Dirty Read 발생

    Read Committed

    • commit , rollback 이 완료되면 다른 트랜잭션에서 읽기 가능한 트랜잭션 격리 수준
    • Dirty Read 문제 해결 가능, Non-Repeatable Read 발생

    Repeatable Read

    • 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장하는 격리수준
    • 트랜잭션 내에서 삭제, 변경에 대해서 언두 로그에 백업하고 앞서 발생한 트랜잭션에 대해서는 언두 로그에 백업되어 있는 내용을 읽는다.
    • Mysql의 InnoDB에서 사용되는 기본 격리수준
    • MVCC를 이용해 한 트랜잭션 내에서 동일한 결과를 보장
    • Non-repeatable read가 발생하지 않음, Phantom Read는 발생
    • 새로운 레코드가 추가되는 경우에 부적합
    MVCC (Multi- Version Concurrency Control, 다중 버전 동시성 제어) 트랜잭션은 고유한 번호를 가지면 언두 영역에 백업된 모든 레코드에는 변경을 발생시킨 트랜잭션 번호도 같이 포함된다. 하나의 트랜잭션 안에서 실행된 모든 select 쿼리는 자신의 트랜잭션 번호보다 작은 트랜잭션 에서 변경된 사항들만 확인 가능하다. RDBS에서는 변경 전의 레코드를 언두 공간에 백업 (변경 전/후 데이터가 모두 존재) 이를 MVCC라고 부른다.

    Serializable

    • 가장 엄격한 격리 수준
    • 트랜잭션을 순자적으로 진행 (여러 트랜잭션이 동일한 레코드에 동시 접근 불가)
    • 단점: 트랜잭션이 순차적으로 진행되기 때문에 성능이 떨어짐

    트랜잭션 락

    비관적 락

    • 비관적 락이란 트랜잭션이 시작될 때 Shared Lock 또는 Exclusive Lock을 걸고 시작하는 방법
      • 공유 락(Shared Lock): Read Lock 이라고 불리는 공유락은 트랜잭션이 읽기를 수행할 때만 사용되는 락이며, 데이터를 읽기만하기 때문에 같은 공유락 끼리는 동시에 접근이 가능, write 는 불가능
      • 배타적 락(Exclusive Lock): Write Lock이라고도 불리며, 데이터를 변경할 때 사용하는 락이다. 트랜잭션이 완료될 때까지 실행되며 배타락이 종료될 때 까지 read/write 를 막는다.

    낙관적 락

    • 낙관적 락이란 자원에 락을 걸지 않고 동시성 문제가 발생하면 그 때 처리하는 방법
    • 낙관적 락은 수정했다고 명시하는 컬럼을 하나 추가하며 다른 트랜잭션이 동일한 조건으로 값을 수정할 수 없게 하는것
      • 낙관적 락은 version과 같은 별도의 컬럼을 추가하여 충돌 발생을 막는다.
      • 충돌이 발생했을때, DB가 아닌 애플리케이션 단에서 처리 한다.
    JPA에서는 @Version 어노테이션을 통해 낙관적 락을 사용할 수 있다. 낙관적 락이 발생할 경우 ObjectOptimisticLockingFailureException 예외가 발생하며 어플리케이션 단에서 예외를 처리해줘야 한다.

    Transactional ReadOnly

    Oracle에서 Transactional Read Only = true 할 때 이점

    • 트랜잭션이 시작되기 전에 커밋된 데이터만 읽을 수 있다.
    • 트랜잭션 도중 커밋된 새로운 데이터는 무시됨
    • 트랜잭션 안에서는 SELECT만 가능 (INSERT/UPDATE/DELETE 불가)
    • 목표는 단순 성능이 아니라 일관성 있는 조회 데이터 확보

    Oracle은 트랜잭션이 시작된 시점의 데이터 상태를 기준으로 일관되게 SELECT 결과를 보장한다.

    트랜잭션이 시작되었을 때, 그 시점의 데이터를 메모리에 스냅샷 처럼 고정해두고 트랜잭션이 끝날 때까지는 이 상태를 기준으로 조회만 허용한다.

    propagation 옵션

    1. REQUIRED

    -> 현재 트랜잭션이 존재하면 그 트랜잭션에 참여하고, 없으면 새 트랜잭션을 시작한다.

    • 호출한 쪽에 트랜잭션이 이미 있으면 재사용
    • 호출한 쪽에 트랜잭션이 없으면 새로 생성

    2. REQUIRES_NEW

    -> 기존 트랜잭션 중단하고 새로운 트랜잭션 시작

    3. SUPPORTS

    -> 트랜잭션 있으면 참여, 없으면 트랜잭션 없이 실행

    4. NOT_SUPPORTED

    -> 트랜잭션 있으면 중단하고 트랜잭션 없이 실행

    5. MANDATORY

    -> 트랜잭션이 반드시 있어야 실행 가능 (없으면 예외 발생)

    6. NEVER

    -> 트랜잭션이 있으면 예외 발생

    7. NESTED

    -> 내부 트랜잭션처럼 동작하되, 별도로 롤백 가능(Savepoint 기반)

Designed by Tistory.