Skip to content

Latest commit

 

History

History
130 lines (85 loc) · 7.1 KB

File metadata and controls

130 lines (85 loc) · 7.1 KB

트랜잭션 Part 2

트랜잭션 ACID

원자성, 일관성, 고립성, 지속성

원자성 (Atomicity)

  • 사전적 의미

    원자성은 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다.
    즉, 작업이 중간 단계까지만 실행되고 실패하는 일이 없도록 하는 것이다.

  • 기능적 의미

    원자적 연산을 보장해야 한다. ⇒ All or Nothing

    MySQL에서는 MVCC를 통해 지원해 준다.

    트랜잭션이 Atomicity한 단위가 된다.

일관성 (Consistency)

  • 사전적 의미

    트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것

  • 기능적 의미

    트랜잭션의 종료되었을 때 데이터 무결성 보장된다.

    제약조건을 통해 ⇒ 유니크 제약, 외래키 제약 등

고립성(Isolation)

  • 사전적 의미

    트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다.

    성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다.

  • 기능적 의미

    트랜잭션은 서로 간섭하지 않고 독립적으로 동작한다. ⇒ 하지만 많은 성능을 포기해야 하므로 개발자가 제어 가능 ⇒ 트랜잭션 격리레벨을 통해 제거 (Undo logMVCC)

지속성(Durability)

  • 사전적 의미

    성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.

  • 기능적 의미

    완료된 트랜잭션은 유실되지 않는다.

    WAL(Write ahead logging)을 통해서 이루어진다.

    • WAL (Write ahead loggin)
      > 트랜잭션이 일어나기 전에 로그를 미리 기록하여 트랜잭션 undo, redo를 할 수 있도록 한다.
      > 변경을 로깅한 후에만, 즉 변경 내용을 설명한는 로그 레코드를 영구적 저장소에 먼저 기록한 후에 데이터 파일(테이블과 인덱스가 있는)의 변경 내용을 작성해야 한다는 것이다.
      > 위의 내용을 준수한 경우 충돌 발생 시 로그를 사용하여 데이터베이스를 복수할 수 있으므로 트랜잭션 커밋마다 데이터 페이지를 디스크에 쓸 필요가 없다. 데이터 페이지에 적용되지 않은 변경 내용은 로그 레코드에서 실행 취소가 가능하다.

격리 수준 (Isolation)

동시에 여러 트랜잭션이 진행될 때 트랜잭션의 작업 결과를 여타 트랜잭션에게 어떻게 노출할 것인지를 결정한다.

트랜잭션 격리성으로 발생할 수 있는 문제점

  • Dirty Read dirty-read.jpg

    • 정의 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 변경 내용을 읽는 것을 Dirty Read라고 합니다.
    • 설명 하나의 트랜잭션이 데이터를 변경하고 아직 커밋하지 않은 상태에서, 다른 트랜잭션이 해당 변경된 데이터를 읽게 되면 더티 리드가 발생합니다.
      이 경우, 첫 번째 트랜잭션이 롤백되면 읽은 데이터가 사라지기 때문에 데이터 무결성이 깨질 수 있습니다.
  • Non Repeatable Read repeatable-read.jpg

    • 정의

      하나의 트랜잭션이 같은 데이터를 두 번 읽을 때, 중간에 다른 트랜잭션이 해당 데이터를 변경하고 커밋하여 두 번의 읽기 결과가 다른 경우를 Non Repeatable Read라고 합니다.

    • 설명

      트랜잭션이 동일한 데이터를 여러 번 읽을 때, 중간에 다른 트랜잭션이 해당 데이터를 수정하고 커밋하면 첫 번째 읽을 결과와 두 번째 읽은 결과가 다를 수 있습니다.

  • Phantom READ phantom.jpg

    • 정의

      트랜잭션이 범위 내의 데이터를 읽을 때, 중간에 다른 트랜잭션이 데이터를 추가 또는 삭제하여 트랜잭션이 읽은 데이터 집합이 변경되는 경우

    • 설명

      트랜잭션이 범위 내의 데이터를 읽을 때, 범위에 속하는 데이터가 다른 트랜잭션에 의해 추가되거나 삭제되면, 처음에는 없던 데이터가 나타나거나 사라질 수 있습니다.

Isolation 5가지 수준

Isolation level Dirty Read Non-repeatable read Phantom read
Read uncommitted Y Y Y
Read comitted N Y Y
Repeatable read N N Y
Serializable N N N
  1. DEFAULT
    • 사용하는 데이터 엑세스 기술 또는 DB 드라이버의 디폴트 설정에 따름
    • 일반적으로 드라이버 격리 수준은 DB의 격리 수준을 따르며, 대부분의 DB는 READ_COMMITED를 기본 격리 수준으로 가짐
  2. READ_UNCOMMITTED (읽기 미확정)
    • 가장 낮은 격리수준으로써 하나의 트랜잭션이 커밋되기 전에 그 변화가 다른 트랜잭션에 그대로 노출되는 문제를 가진다.
    • 가장 빠른 속도를 가지므로 데이터의 일관성이 떨어지더라도 의도적으로 사용될 수 있다.
    • Dirty Read, Phantom Read, Non-Repeatable Read 문제
  3. READ_COMMITTED (읽기 확정)
    • Spring은 기본 속성이 DEFAULT이며, DB는 일반적으로 READ_COMMITED가 기본 속성으로 사용된다.
    • 가장 많이 사용되는 속성이다.
    • READ_UNCOMMITED와 달리 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없다.
    • 하나의 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정할 수 있어서 처음 트랜잭션이 같은 로우를 다시 읽을 때 다른 내용이 발견딜 수 있음
    • Phantom Read, Non-Repeatable Read 문제
  4. REPEATABLE_READ (반복 가능한 읽기)
    • 하나의 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정할 수 없도록 막아주지만 새로운 로우를 추가하는 것은 막지 않는다.
    • 따라서 SELECT로 조건에 맞는 로우를 전부 가져오는 경우 트랜잭션이 끝나기 전에 추가된 로우를 발견할 수 없다.
    • Phantom Read 문제
  5. SERIALIZABLE (직렬화 가능한 읽기)
    • 가장 강력한 트랜잭션 격리 수준으로, 이름 그대로 트랜잭션을 순차적으로 진행시켜준다.
    • SERIALIZABLE 은 여러 트랜잭션이 동시에 같은 테이블의 정보를 엑세스 할 수 없다.
    • SERIALIZABLE 은 가장 안전하지만 가장 성능이 떨어지므로 극단적으로 안전한 작업이 필요한 경우가 아니라면 사용해서는 안된다.