Transaction

eden6187·2021년 3월 9일
0

DB

목록 보기
2/6
post-thumbnail

이 개념은 왜 등장했는가?

Transaction은 다음과 같은 2가지 필요성에 의해 만들어졌다.

[ 동시성 제어 - concurrency control ) ]

  • DBMS는 필연적으로 여러 User가 동시에 사용한다.

  • 하지만 무분별하게 동시에 명령을 수행하게 되면 문제가 발생한다!

[ 회복 - recovery ]

  • 시스템에 문제가 발생해도 각각의 User들의 요청이 중간에 어정쩡하게 끝나서는 안된다!

그래서 트랜잭션이 뭔가?

[ 트랜잭션이란? ]

데이터베이스의 일의 단위 ( a unit of datbase work )를 트랜잭션이라 한다.

[ 트랜잭션의 4대 특징 - ACID ]

특징설명
Atomicity( 원자성 )- 데이터 조작이 전부 성공 혹은 실패 해야 한다.
- COMMIT : 조작 과정에 문제 없으면 처리 확정
- ROLLBACK : 조작 중간에 문제 발생 시 첫 과정 직전 상태로 복귀
Consistency( 일관성 )- 데이터 조작 전후에 일관성을 유지해야 한다.
Isolation( 고립성 )- 동시에 데이터 조작을 실행할 경우 각각의 처리가 모순 없이 실행되는 것을 보증해야 한다.
Durability( 지속성 )- 트랜잭션이 COMMIT이 되고 나면 변경 사항이 영구적으로 확정되도록 보장해야 한다.

이렇게 딱딱한 말로만 읽으면 이해가 잘 안된다. 개인적으로 이해한 바는 다음과 같다.

  1. ATOMICITY - 원자성

    • ALL or NOTHING 즉, 트랜잭션은 쪼개 져서 수행 되어서는 안된다.
  2. CONSISTENCY - 일관성

    • 개인적으로 CONSISTENCY가 이해가 잘 안되었는데 말 그대로 그냥 받아들이면 된다. 트랜잭션을 수행 한 이전과 이후 데이터베이스가 일관성을 유지해야 한다는 것이다.
  3. ISOLATION - 고립성

    • 동시성과 연관된 개념이라는 것을 이해해야 한다. 표에 있는 그대로 받아들이면 된다.
  4. DURABILITY - 지속성

    • 한 트랜잭션이 커밋되면 시스템에 고장이 발생하더라도 손실되지 않는다. 시스템이 고장난 경우에도 데이터베이스에 반영된다.

DBMS가 이러한 트랜잭션의 특징을 만족시키기 위해서는 하나의 트랜잭션이 완벽하게 끝난 이후에 다른 트랜잭션을 수행하는 방식으로 처리를 하는 것이 가장 이상적이지만 이렇게 되면 DB의 가장 중요한 특징중 하나인 동시성을 만족시키지 못하게 된다. 그래서 필요한 개념이 Isolation Level ( 격리 수준 )이다.

[ ANSI 표준 격리 수준 - Isolation Level ]

격리 수준
( 아래로 갈수록 강해짐 )
설명
Read Uncommitted- 트랜잭션에서 처리 중인 아직 COMMIT 되지 않은 읽기를 허용한다.
Read Committed- 트랜잭션이 COMMIT 확정된 데이터만 다른 트랜잭션이 읽도록 허용한다.
Repeatable Read- 같은 쿼리를 두 번 이상 수행할 때, 첫 번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌는 현상을 방지하기 위해 사용한다.
Serializable- 같은 쿼리를 두 번 이상 수행할 때, 첫번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌지 않음은 물론 새로운 레코드가 나타나지도 않는 것을 보장하기 위해 사용한다.
  • Serializable로 DB를 운용하는 것이 Transaction을 처리하는 것에가장 이상적이지만 이렇게 되면 동시성이 떨어져서 성능이 저하된다...

  • DBMS의 격리 수준에 따라 default로 설정된 격리 수준이 다르고 MVCC 기능이 없는 DBMS의 경우 Read Uncommited가 기본 격리 수준으로 설정된다. ( 고급 개념 )

  • 격리 수준이라는 것은 Transaction 별로 설정해주어야 한다.

이렇게 딱딱한 말로만 읽으면 이해가 잘 안된다. 각각의 사례를 자세히 살펴보자!


[ 격리 수준을 낮추었을 때 발생하는 현상들 ]

현상 종류설명
Dirty Read- 트랜잭션에서 처리 중인 아직 COMMIT 되지 않은 읽기를 허용한다.
- 아직 커밋 되지 않은 값을 읽었는데 변경을 가한 트랜잭션이 최종적으로 롤백 된다면 그 값을 읽은 트랜잭션은 비 일관된 상태에 놓이게 된다.
Non-Repeatable Read- 한 트랜잭션 내에서 같은 쿼리를 두 번 수행했는데, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제하는 바람에 두 쿼리 결과가 다르게 나타나는 현상
Phantom Read- 한 트랜잭션 내에서 같은 쿼리를 두 번 이상 수행할 때, 없던 레코드가 두 번째 쿼리에서 나타나는 현상

역시 딱딱한 말로만 읽으면 이해가 잘 안된다. 각각의 사례를 자세히 살펴보자!

  • Dirty Read : Dirty data item은 아직 커밋되지 않은 transaction에 의해서 쓰여진 값을 의미한다. 그리고 이러한 데이터를 읽는 것을 Dirty Read라고 한다.

즉, 지금 까지의 내용을 정리해보자면 다음과 같다.

  • 트랜잭션은 ACID를 만족해야 한다.

  • 따라서 Serializable로 DB를 운용하는 것이 Transaction을 처리하는 것에 가장 이상적이지만 이렇게 되면 동시성이 떨어져서 성능이 저하된다...

  • 동시성과 격리성은 Trade-off 관계이다.

  • 따라서 Serializable보다 낮은 격리 수준으로 DBMS가 운용되고 그로 인해 발생 할 수 있는 여러가지 문제 현상들이 발생하게 된다.


[ 격리 수준과 문제 현상 가능성 ]

격리 수준Dirty ReadNon-Repeatable ReadPhantom Read
Read UncommittedOOO
Read committedXOO
Repeatable ReadXXO
Read UncommittedXXX

  • 개인적으로 헷갈렸던 부분 1
    Repeatable Read에서 Phantom Read가 발생할 수 있는 이유는 Repeatable Read는 '기존의 튜플들'의 변경 여부만을 확인하기 때문이다. 새로운 튜플들이 추가 되는 것이 '기존'에 존재하던 튜플에 영향을 주는 행위는 아니기 때문에 Phantom Read가 발생한다.

  • 개인적으로 헷갈렸던 부분 2
    Read Committed에서 Non-Repeatad가 발생할 수 있는 이유는 다음과 같다.

[ 락(Lock) 과 데드락(Deadlock) ]

  • 동시성과 일관성을 동시에 잡기위해서 데이터베이스의 락은 필수적이다.
  • 락에는 공유락과 배타락 2가지 종류가 있다.
  • 데드락은 운영체제 시간에 배우는 데드락 개념과 같다.

이렇게 쓰면 좋을거 같아요

  • Read Uncommited - 정확하지 않더라도( 즉, 일관되지 않더라도 ) 대략적인 결과를 빨리 알고 싶을 경우에 사용

  • Table 전체에 대해서 종합된 결과를 조회 하고자 한다면 Repeatable Read로는 부족 할 수 있다.(뇌피셜..)

이렇게는 쓰는건 별로...?

  • 무조건 Serializable로 설정 - 성능 측면에서 너무 좋지 않다.

참조

관련 개념

  • MVCC 기능

0개의 댓글