Gidhub BE Developer

트랜잭션 고립화 레벨(Transaction Isolation Level)

2018-10-08
goodGid
DB

Isolation Level의 필요성

  • DB는 무결성을 보장하는 것이 중요하다.

    그리고 그 무결성을 보장하기 위한 특징이 ACID(Atomicity, Consistency, Isolation, Durability)이다.

    DB는 ACID가 의미하는 바와 같이 Transaction원자적이면서도 독립적인 수행을 하도록해야 한다.

    그래서 등장하는 개념이 Locking이다.

  • Locking은 Transaction이 DB를 다루는 동안 다른 Transaction이 관여하지 못하게 막는다.

    하지만 무조건적인 Locking으로

    동시에 수행되는 많은 Transaction들을 일렬로 대기시킨다면 DB의 성능은 현저하게 떨어진다.

  • 반대로 응답성을 높이기 위해

    Locking 범위를 줄인다면 잘못된 값이 처리 될 여지가 있다.

    그래서 최대한 효율적인 Locking 방법이 필요하다.

    이와 관련된 Locking 방법이 Isolation Level이다.


Isolation Level의 종류

Read Uncommitted

  • Select 문장을 수행하는 경우 해당 데이터Shared Lock이 걸리지 않는 Level이다.

  • 따라서 어떤 사용자가 A -> B로 데이터를 변경하는 동안

    다른 사용자는 완료되지 않은(Uncommitted 혹은 Dirty Data) B를 읽을 수 있다.

  • 즉 Transaction이 끝나지 않은 상황에서

    각기 다른 Transaction변경한 내용에 대한 조회가 가능하다.

    그렇게 되면 데이터베이서의 일관성을 유지할 수 없다.

  • Transaction1이 최초 수행되고

    그 뒤에 Transaction2가 값을 변경할 경우

    다시 Transaction1이 조회를 하게 되면

    Transaction2가 Commit은 하지 않았지만

    이미 Transaction2가 값을 변경하였기 때문에

    아무개 에서 개발자 로 값이 변경되어 조회가 된다.


Read Committed

  • SQL Server가 Default로 사용하는 Isolation Level이다.

  • 이 Level에선 Select 문장이 수행되는 동안 해당 데이터Shared Lock이 걸린다.

  • 그러므로 어떠한 사용자가 A -> B로 데이터를 변경하는 동안

    다른 사용자는 해당 데이터에 접근할 수 없다.

  • Read Uncommitted와 다르게 Commit이 이루어진 데이터조회된다.

  • 하지만 어떠한 사용자가 A -> B로 데이터를 변경하는 동안

    다른 Transaction은 접근할 수 없어 대기하게 된다.

  1. Transaction2가 Update를 하게된다.

  2. 아직 Commit하지 않아 Transaction1은 Select을 하지 못하고 대기하게 된다.

  3. Transaction2가 Commit명령어를 날리게 된다.

  4. 이제 Transaction2는 조회가 가능하다.


Repeatable Read

  • Transaction이 완료될 때까지

    Select 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로

    다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다.

  • 가령 Select col1 from A Where col1 between 1 and 10 을 수행하였고

    이 범위에 해당하는 데이터가 2건이 있는 경우 (col1 = 1,5)

    다른 사용자가 col1 = 1 혹은 col1 = 5인 Row에 대한 Update 작업이 불가능하다.

    하지만 col1이 1과 5를 제외한

    나머지 범위에 해당하는 Row를 Insert하는 것은 가능하다.

  • 그 결과 Transaction이 최초 수행된 후

    해당 범위내에서는 조회한 데이터의 내용이 항상 동일함을 보장한다.

  1. Transaction1이 Select시점에 아무개가 조회된다.

  2. Transaction2가 Update후 Commit을 시행하였지만 Update가 안된다.
    그러나 Insert는 된다.

  3. Transaction1이 다시 조회 해도 Transaction2가 Commit이 되지 않았기 때문에 아무개로 조회된다.
    하지만 Insert한 동네개발자는 조회된다.

  4. Transaction1이 종료되면 다시 Commit이 이루어지기 때문에 개발자로 조회가 된다.


Serializable

  • Index가 설정되어 있지 않다는 조건하에

    모든 동작직렬화되어 동작한다.

  • 그러므로 Repeatable Read와 다르게

    Insert를 하여도 동작하지 않게 된다.

  • Transaction이 완료될 때까지

    Select 문장이 사용하는 모든 데이터Shared Lock이 걸리므로

    다른 사용자는 그 영역에 해당하는 데이터에 대한 Update 및 Insert가 불가능하다.

  • 기본적으로는 위 개념처럼 동작하지만

    Index가 설정되어 있다면 조금 다르게 동작한다.

Index 설정 O

  • Table에 총 1~10 sequence가 있고

    A Transaction이

    select * from table_name where 3 <= seq <= 5 를 조회하는 상황에서

    B Transaction이 데이터를 insert를 하려고 하면

    Index 값을 보고 Success / Fail을 하게 된다.

Insert seq = 1~2 ==> Success
Insert seq = 3~5 ==> Fail
Insert seq = 6~10 ==> Success

Index 설정 X

  • Index가 설정되어 있지 않으면

    기본적으로 모든 데이터에 대해 Lock을 걸어버린다.

    그래서 모든 Insert 요청이 실패한다.

Insert seq = 1~2 ==> Fail
Insert seq = 3~5 ==> Fail
Insert seq = 6~10 ==> Fail


부작용(Side Effect)

Dirty Read

  • A Transaction 입장에서

    아직 실행이 끝난지 않은 B Transaction에 의한 변경 사항을 보게되는 경우를 Dirty Read라고 한다.

  • 만약 수정한 Transaction이 그 변경 사항을 롤백하면

    그 데이터를 읽은 다른 Transaction은 Dirty 데이터를 가지고 있다고 말한다.


Non-Repeatable Read

  • A Transaction에서 같은 질의를 여러번 하여도

    B Transaction에서 변경한 사항을 반영하지 못하고

    변경되기전의 같은 데이터만 읽어드리는 경우를 Non-Repeatable Read라고 한다.

  • 즉 Non-Repeatable Read Level을 사용하는 DB에서는

    다른 Transaction에 의한 변경 사항을 볼 수가 없다.

    변경 사항을 보고 싶다면 Application에서 Transaction을 새로 시작해야 한다.


Phantom Read

  • Phantom Read는 다른 Transaction에 의한 변경 사항으로 인해

    현재 사용 중인 Transaction의 Where 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것이다.

  • 예를 들어 잔고가 $100 미만인 계좌가 2개인 DB에서

    $100 미만인 계좌를 찾는 Transaction이 있고

    그 Transaction안에서 Select 쿼리를 2번 수행한다고 가정하자.

    처음에 데이터를 읽으면 2개의 계좌를 찾게 된다.

    이 때 다른 Transaction에서 $0인 계좌를 새로 만들면

    두번째 데이터를 읽을 땐 3개의 계좌를 찾게 된다.

  • 이처럼 Where 절의 조건에 맞는 새로운 행이 생길 수 있는 경우를 말한다.

  • DB의 Transaction Isolation Level에서 Phantom Read지원하면

    새로운 유령(phantom)행이 나오지만 지원하지 않으면 새로 생긴 행을 볼 수 없다.


추가 정보


Reference


Index