Post

트랜잭션 이해





트랜잭션이란

  • DB에서 수행되는 일련의 작업들로 이뤄진,
  • 하나의 논리적인 작업 단위이다.
  • 작업 처리 중에 일어날 수 있는 오류나 사고 등으로 데이터가 예상하지 못한 상태가 되는 것을 방지하기 위함이다.
    • 예를 들어, A의 통장에서 B의 통장으로 이체를 한다면
    • A의 잔고에서 100원이 나갔다.
    • B의 잔고에서 100원이 들어오려 할 때, 디비가 터져버렸다.
    • 다시 복구를 시켰더니 A의 잔고에서는 100원이 분명히 사라졌는데,
    • B의 잔고에는 100원이 들어오지 않았다.
    • A의 잔고에서 100원이 나가는 과정과 B의 잔고에 100원이 들어오는 과정이 하나의 과정으로 묶어 사고를 방지할 수 있다.
    • 여러 과정을 묶어 하나의 과정으로 만든 것이 트랜잭션이다.



트랜잭션의 사용

  • 트랜잭션에는 두 가지 동작이 있다.
    • commit
      • 트랜잭션 내의 일련의 디비 조작 명령을 실행하고,
      • 그 실행의 결과를 디비에 반영하는 것이다.
    • rollback
      • 트랜잭션 작업 수행의 결과를 저장하지 않고,
      • 트랜잭션 시작 전의 상태로 되돌려 놓는 것이다.
    • 조회야 뭐 상관없고, 변경이 반영되느냐 롤백되느냐 하는 것이다.
    • A 세션의 트랜잭션에서 변경이 일어났고, 아직 커밋되지 않았다.
      • 다른 세션인 B에서 A에서 변경이 일어난 데이터를 조회하면, A에 의한 변경은 보이지 않는다.
      • 만약 세션 B에서 커밋되지 않은 A의 변경이 보인다면, 데이터 정합성 문제가 생긴다.
        • 세션 A가 롤백을 해버린다면,
        • B는 롤백이 된줄 모르고 변경된 데이터를 사용해버리면 정합성이 깨진다.



자동 커밋과 수동 커밋

  • 자동 커밋
    • 쿼리 한 줄마다 자동으로 커밋을 해주는 것이다.
    • 편리하지만 트랜잭션 기능을 사용할 수 없다.
    • 기본적으로 활성화되어 있다.
  • 수동 커밋
    • 작업이 끝나고 마지막에 커밋 또는 롤백을 해줘야하는 것.
    • 커밋이나 롤백을 명시해주지 않으면 타임아웃 뒤에 그냥 롤백이 되어버린다.
    • 수동 커밋으로 바꾸면 세션이 유지되는 동안에 수동 커밋도 유지된다.


ACID

  • 트랜잭션이 갖춰야 하는 네 가지 속성을 의미한다.
  • Atomicity
    • 원자성
    • 트랜잭션 내의 작업들은 전체가 하나의 작업으로,
    • 누구는 성공하고, 누구는 실패했다는 개념이 없다.
    • 전체가 성공했거나, 전체가 실패했다만 있다.
  • Consistency
    • 일관성
    • 모든 트랜잭션은 일관성 있는 디비 상태를 유지해야 한다.
    • 디비에서 정한 무결성 제약 조건을 잘 지켜야 한다.
  • Isolation
    • 고립성
    • 여러 트랜잭션들이 수행될 때, 서로의 결과에 영향을 주지 않아야 한다.
    • A 아이템을 a 트랜잭션이 잡고 작업을 수행할 때,
    • b 트랜잭션도 A 아이템을 변경하는 작업을 수행한다면 기다린다던가 해야한다.
  • Durability
    • 지속성
    • 트랜잭션이 커밋되면 항상 DB에 반영이 되어야 한다.
    • 만약 시스템 오류나 어떤 사고로 트랜잭션이 디비에 반영되지 않았더라도,
    • 로그를 확인하여 다시 작업하는 등의 복구를 해야한다.



고립성의 단계

  • 고립성을 완벽히 지키기 위해서는 트랜잭션들을 하나하나 순차적으로 처리해야 한다.
    • 이러면 성능적으로 너무 떨어지게 된다.
  • 성능을 위해서 격리성을 지키지 않는다면,
    • 여러 트랜잭션들에 의해 예상치 못한 결과가 디비에 들어가고 만다.
  • 이러한 고립성을 ANSI에서 표준화하여 4단계로 나누었다.


  • Read Uncommitted
    • 어느 한 트랜잭션에서 어떤 데이터 A를 작업하고 있는 도중에, (아직 커밋이나 롤백되지 않은 상태)
    • 다른 트랜잭션에서 A의 값을 읽을 수 있다.
  • Read Committed

  • Repeatable Read
  • Serializable


Isolation LevelDirty ReadNon-repeatable ReadPhantom Read
Read UncommittedPossiblePossiblePossible
Read CommittedNot PossiblePossiblePossible
Repeatable ReadNot PossibleNot PossiblePossible
SerializableNot PossibleNot PossibleNot Possible


  • Dirty Read
    • 다른 트랜잭션에 의해 변형이 일어난, 커밋은 되지 않은 데이터를 읽는 것을 말한다.
  • Dirty Write
    • 백수 아들의 통잔 잔고가 1000원이었다고 한다.
    • 엄마가 아들의 잔고를 조회중이다.
    • 거의 동시에 아빠도 아들의 잔고를 열어보았다.
    • 엄마는 백수 아들이 안쓰러워 10000원을 입금해 주었다.
      • 엄마의 세션에서 아들의 잔고가 11000원이 되었다.
      • 아직 커밋은 하지 않았다.
    • 아빠 역시 백수 아들이 안타까워 10000원을 입금해 주었다.
      • 아빠의 세션에서 아들의 잔고가 11000원이 되었다.
      • 아직 커밋은 하지 않았다.
    • 엄마가 먼저 커밋을 했다.
      • 아들의 잔고가 11000원으로 디비에 반영되었다.
    • 아빠가 뒤따라서 커밋을 했다.
      • 아들의 잔고가 11000원으로 디비에 반영되었다.
    • 엄마 아빠가 각각 만원씩 입금을 해주셨지만, 안타깝게도 백수 아들은 만원만 받았다.
    • 이것을 더티 쓰기라고 한다.
  • Non-repeatable Read
    • 한 트랜잭션 내에서 같은 쿼리를 수행했는데, 결과가 다르게 나오는 경우를 말한다.
    • 예를 들어,
      • A 트랜잭션에서 어떤 값을 조회해서 10이 나왔다.
      • A 트랜잭션이 그 값에 10을 곱하면 100이 된다.
      • 그 다음 B 트랜잭션이 같은 값에 10을 더해서 결과는 110이 된다.
    • 그러나 Non-repeatable Read가 일어난다면,
      • A 트랜잭션이 조회한 값이 10이 나왔다.
      • A 트랜잭션이 그 값에 10을 곱하려고 할 때, B가 10을 더하고 커밋 해버렸다.
        • 처음 조회한 값 10과 다른 값 20이 나와버렸다.
      • A가 커밋되었을 때 그 값음 200이 되어버렸다.
  • Phantom Read
    • 한 트랜잭션에서 일정 범위의 레코드들을 두 번 이상 읽을 때,
    • 처음에 없었던 레코드(유령 레코드)가 나오는 현상이다.
    • 예를 들어,
      • A 트랜잭션에서 봉천의 20대들을 조회했다.
        • 여기서 100명이 조회되었다.
      • 그때 B 트랜잭션이 봉천동에 20대 보근의 전입신고를 커밋했다.
      • A 트랜잭션은 봉천의 20대들을 group by 성별로 count() 했다.
      • 왜인지 남녀 합계가 101명이었다.



DB 락

  • 위에서 발견한 여러가지 트랜잭션에서 일어나는 문제들을 해결하기 위해서
  • 어느 한 트랜잭션이 어떤 레코드 A를 사용하는 동안에는 다른 트랜잭션이 레코드 A를 변경할 수 없게 잠구는 방법이다.
    • 대신 락 time out이 있어서 그 시간이 지나면 자동으로 락이 풀린다.
  • 그걸 락이라고 한다.



DB 락 - 변경

-





This post is licensed under CC BY 4.0 by the author.