이 개념은 왜 등장했는가?
Transaction은 다음과 같은 2가지 필요성에 의해 만들어졌다.
[ 동시성 제어 - concurrency control ) ]
DBMS는 필연적으로 여러 User가 동시에 사용한다.
하지만 무분별하게 동시에 명령을 수행하게 되면 문제가 발생한다!
[ 회복 - recovery ]
그래서 트랜잭션이 뭔가?
데이터베이스의 일의 단위 ( a unit of datbase work )를 트랜잭션이라 한다.
특징 | 설명 |
---|---|
Atomicity( 원자성 ) | - 데이터 조작이 전부 성공 혹은 실패 해야 한다. - COMMIT : 조작 과정에 문제 없으면 처리 확정 - ROLLBACK : 조작 중간에 문제 발생 시 첫 과정 직전 상태로 복귀 |
Consistency( 일관성 ) | - 데이터 조작 전후에 일관성을 유지해야 한다. |
Isolation( 고립성 ) | - 동시에 데이터 조작을 실행할 경우 각각의 처리가 모순 없이 실행되는 것을 보증해야 한다. |
Durability( 지속성 ) | - 트랜잭션이 COMMIT이 되고 나면 변경 사항이 영구적으로 확정되도록 보장해야 한다. |
이렇게 딱딱한 말로만 읽으면 이해가 잘 안된다. 개인적으로 이해한 바는 다음과 같다.
ATOMICITY - 원자성
CONSISTENCY - 일관성
ISOLATION - 고립성
DURABILITY - 지속성
DBMS가 이러한 트랜잭션의 특징을 만족시키기 위해서는 하나의 트랜잭션이 완벽하게 끝난 이후에 다른 트랜잭션을 수행하는 방식으로 처리를 하는 것이 가장 이상적이지만 이렇게 되면 DB의 가장 중요한 특징중 하나인 동시성을 만족시키지 못하게 된다. 그래서 필요한 개념이 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 | - 한 트랜잭션 내에서 같은 쿼리를 두 번 이상 수행할 때, 없던 레코드가 두 번째 쿼리에서 나타나는 현상 |
역시 딱딱한 말로만 읽으면 이해가 잘 안된다. 각각의 사례를 자세히 살펴보자!
즉, 지금 까지의 내용을 정리해보자면 다음과 같다.
트랜잭션은 ACID를 만족해야 한다.
따라서 Serializable로 DB를 운용하는 것이 Transaction을 처리하는 것에 가장 이상적이지만 이렇게 되면 동시성이 떨어져서 성능이 저하된다...
동시성과 격리성은 Trade-off 관계이다.
따라서 Serializable보다 낮은 격리 수준으로 DBMS가 운용되고 그로 인해 발생 할 수 있는 여러가지 문제 현상들이 발생하게 된다.
격리 수준 | Dirty Read | Non-Repeatable Read | Phantom Read |
---|---|---|---|
Read Uncommitted | O | O | O |
Read committed | X | O | O |
Repeatable Read | X | X | O |
Read Uncommitted | X | X | X |
개인적으로 헷갈렸던 부분 1
Repeatable Read에서 Phantom Read가 발생할 수 있는 이유는 Repeatable Read는 '기존의 튜플들'의 변경 여부만을 확인하기 때문이다. 새로운 튜플들이 추가 되는 것이 '기존'에 존재하던 튜플에 영향을 주는 행위는 아니기 때문에 Phantom Read가 발생한다.
개인적으로 헷갈렸던 부분 2
Read Committed에서 Non-Repeatad가 발생할 수 있는 이유는 다음과 같다.
이렇게 쓰면 좋을거 같아요
Read Uncommited - 정확하지 않더라도( 즉, 일관되지 않더라도 ) 대략적인 결과를 빨리 알고 싶을 경우에 사용
Table 전체에 대해서 종합된 결과를 조회 하고자 한다면 Repeatable Read로는 부족 할 수 있다.(뇌피셜..)
이렇게는 쓰는건 별로...?
참조
관련 개념