ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Chapter 7. Transaction
    Database 2021. 2. 20. 16:55

    1. Transaction이란

    트랜잭션은 DB에서 논리적 작업을 처리하기 위한 쿼리 집합으로서, 트랜잭션에 묶인 모든 쿼리를 수행하거나, 모두 실행하지 않는다. 이를 위해 'Log'를 참조하여 'Commit 연산', 'Rollback 연산'을 진행한다.

     

    Commit 연산

    • Commit 연산은 트랜잭션 처리가 정상적으로 종료되어 트랜잭션이 수행한 변경 내용을 DB에 반영하는 연산이다.
    • 트랜잭션이 완료되면, DB는 새로운 정보로 변경되며, 이 정보는 시스템에 오류가 발생하더라도 취소되지 않는다.

     

    Rollback 연산

    • Rollback 연산은 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션이 행한 모든 변경 작업을 취소하고 이전 상태로 되돌리는 연산이다.
    • Rollback 연산 시 해당 트랜잭션은 받았던 자원을 모두 반환하고, 이전 데이터로 원복한다.

    [그림 1] Transaction 예시

    [그림 1]은 성호가 은경에게 5000원을 계좌 이체하는 트랜잭션을 나타낸다. 1, 2SQL Update문의 실행 순서는 상관없지만 두 개다 반드시 실행되어야 한다. 만약 1번만 실행되고 2번은 실행되지 않는다면, 성호가 보낸 5000원은 없어지게 된다. 이런 경우 Rollback 연산을 통해 1SQL Update으로 변경된 결과를 이전 상태로 복구한다.

    즉, 1, 2번 연산이 모두 정상적으로 수행되었을 경우 Commit 연산을 통해 DB에 반드시 반영하고, 하나라도 비정상적 처리가 일어난다면 Rollback 연산을 통해 이전 상태로 원복한다.

     

    트랜잭션을 사용할 때 주의점

    트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다. , 트랜잭션의 범위를 최소화 해야함을 의미한다. 일반적으로 DB 커넥션 개수는 제한적이다. 그런데 어느 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어들게 된다. 트랜잭션의 길이가 길다면 커넥션의 소유시간이 길어짐을 의미하고 다른 프로그램들은 커넥션의 가용갯수가 없다면 대기하고 있어야한다.

    2. Transaction 특성 [ACID]

    Atomicity [원자성]

    • 트랜잭션의 연산은 DB에 모두 반영되던지 아니면 전혀 반영되지 않아야한다. 만약 하나의 쿼리만 실행된다면 데이터의 일관성이 깨지는 문제가 발생한다.
    • 예를 들어 A 계좌에서 B 계좌로 5000원을 이체하는 트랜잭션이 완벽히 수행되면 Commit 연산을 수행해서 DB에 반영하고 트랜잭션 중간에 오류가 발생한다면, Rollback 연산을 수행하여 그 때까지 수행된 트랜잭션 연산을 모도 취소하여 원래의 상태로 만들어야 한다.

    Consistency [일관성]

    • 트랜잭션 수행이 성공 or 실패 하더라도 시스템이 가지고 있는 고정 요소는 트랜잭션 수행 전과 완료 후의 상태와 동일 해야한다.
    • 예를 들어 A 계좌와 B 계좌의 합이 25,000이라면 A 계좌에서 B 계좌로 5,000원을 이체하는 트랜잭션을 수행한 후에도 A 계좌와 B 계좌의 합은 25,000이 되어야한다. 혹은 마이너스 계좌를 보장하지 않는 테이블에서 마이너스 계좌가 나오는 트랜잭션은 종료된다.

     

    Isolation [독립성]

    • 한 트랜잭션이 데이터를 갱신하는 동안 갱신중인 데이터에 다른 트랜잭션들이 접근하지 못하도록 해야 한다. 만약 접근을 허용할 경우 일관성이 깨지는 데이터를 참조할 수 있다.
    • 예를 들어, A 계좌에서 B 계좌로 5,000원을 이체하는 트랜잭션을 수행하는 동안에는 다른 트랜잭션이 A 계좌와 B 계좌에 접근할 수 없어야 한다.

     

    Durability [연속성]

    • 성공적으로 수행된 트랜잭션은 SW, HW 장애가 발생하더라도 영구적으로 반영되어야 한다. 예를 들어, 송금한 금액은 영구적으로 반영된다.

    3. 병행 제어

    동시에 여러 개의 트랜잭션을 병행 수행할 때, 데이터의 일관성은 유지하고 단위 시간당 트랜잭션 처리 건수를 최대화 함을 의미한다.

     

    발생 가능 문제점

    • Lost Update : 2개 이상의 트랜잭션이 같은 데이터를 공유하여 갱신할 때, 데이터가 덮어써져 갱신 결과의 일부가 없어지는 현상을 말한다.
    • Inconsistency : 데이터 갱신이 끝나지 않은 시점에서 다른 트랜잭션이 해당 데이터를 조회하는것 같이 모순된 데이터를 읽는 현상을 말한다.
    • Cascading Rollback : 병행 수행되던 트랜잭션들 중 어느 환경에 문제가 생겨 Rollback되는 경우 다른 트랜잭션들도 Rollback되는 현상을 말한다.

    병행 제어 기법 Locking

    • 하나의 트랜잭션이 데이터를 엑세스 하는 동안 다른 트랜잭션은 그 데이터를 엑세스 할 수 없다. 트랜잭션은 데이터를 엑세스 하기 전에 Lock을 요청하고 엑세스를 마치면 Lock을 해제한다. CRUD의 접근에 Isolation Level을 설정하여 병행성과 일관성을 적절히 유지한다.
    • 하지만 Deadlock의 문제점이 존재한다.

    4. DeadLock

    복수의 트랜잭션을 사용하다보면 교착상태가 일어날 수 있다. 교착상태란 두 개 이상의 트랜잭션이 특정 자원[테이블 혹은 행]의 잠금을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하며 무한 대기하는 상태를 말한다.

     

    교착 상태의 빈도를 낮추는 방법

    • 트랜잭션을 자주 커밋한다.
    • 정해진 순서로 테이블에 접근한다.
    • Isolation Level을 높여 직렬화 상태로 만든다. 동시성은 떨어지지만 교착상태를 피할 수 있다.
    • 자세한 내용은 Operating System의 'Deadlock'을 참조한다.

     

    5. Transaction Isolation Level

    여러 트랜잭션이 동시의 어떤 데이터에 접근할 때, 어디까지 제어할지에 대한 설정을 말한다. 격리 수준을 엄격히 제어하면 데이터의 안정성은 높아지지만, 동시성 성능이 떨어지는 현상이 발생한다. 따라서 상황에 맞게 고립 레벨을 설정하는 것이 좋다. 대부분의 DBRead Committed가 기본 수준이다.

     

    1. READ-UNCOMMITTED

    어떤 트랜잭션의 데이터 변경 내용을 커밋 하기 전에, 다른 트랜잭션이 변경된 내용을 읽을 수 있다.

    Dirty Read : 만약 T-A가 커밋 하지 않고 Rollback 한다면, T-B는 잘못된 데이터를 처리하는 문제가 발생한다.

    [그림 2] Read Uncommitted 예시

    2. READ-COMMITTED

    트랜잭션의 커밋이 완료된 변경사항만 다른 트랜잭션에서 조회가 가능하다.

    Non-Repeatable Read : 같은 트랜잭션 내에서 select문을 조회했는데, 데이터가 다르게 나오는 불일치 문제이다.

    [그림 3] Read Committed 예시

    3. REPEATABLE READ

    트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장한다. , 한번 조회한 내용은 같은 값을 반환한다.

     

    Phantom Read [Non Repeatable Read 현상의 한 종류이다.]

    T1A 테이블에서 데이터를 Select 한 후, T2에서 A 테이블에 데이터를 삽입 or 삭제 하는 상황에서 T1이 다시 A 테이블에서 데이터를 Select 할 경우 데이터가 추가되거나 사라지는 현상이 발생한다.

    [그림 4] Repeatable Read

    4. SERIALIZABLE

    한 트랜젝션에서 사용하는 데이터를 다른 트랜잭션에서 접근 불가하다. 단순 select만으로도 트랜잭션이 Commit 될 때 까지 다른 트랜잭션의 접근이 불가하다.

     

      Dirty Read Non Repeatable Read Phantom Read
    Read Uncommitted o o o
    Read Committed x o o
    Repeatable Read x x o
    Serializable x x x

    6. Transaction Recovery이란

    트랜잭션은 'Commit', 'Rollback'연산을 사용한다. 이때 사용자의 입력 실수, 과도한 시스템 자원 요구, OS 오류 등 외부요인에 의해 각 연산에 문제가 발생할 수 있다. 이를 해결하기 위해 'Redo', 'Undo' 작업을 수행한다. 이 작업을 수행하기 위해서는 정상적으로 실행되기까지의 과정을 기억해야 되는데 이를 'LOG'라고 한다. LOG는 전원이 끊겨도 데이터를 저장할 수 있는 보조 기억 장치에 저장되는 경우가 많다.

     

    REDO 작업

    DB가 비정상적으로 종료되었을 때 로그의 'start''commit' 기록이 있는 트랜잭션들의 작업을 다시 수행한다. , 트랜잭션 실행을 성공적으로 종료하였으나 디스크에는 반영되지 않았을 경우, 로그를 활용하여 재작업을 수행한다.

     

    UNDO 작업

    DB가 비정상적으로 종료되었을 때, 로그의 'start'는 있지만 완료를 나타내는 'commit' 기록이 없는 트랜잭션 작업을 원복한다. , 이전 디스크 상태로 원복한다.

     

    7. Transaction Recovery 기법

    지연 갱신

    트랜잭션 커밋 전까지 DB에 기록하지 않고, Commit 이후 데이터를 반영한다.

    Undo : Commit 이전에 DB에 기록하지 않아 작업이 필요없다.

    Redo : Commit 이후, 오류 발생시 로그를 참조하여 변경 데이터로 DB에 반영한다.

    [그림 5] 지연 갱신

    즉시 갱신

    트랜잭션 수행 도중 변경 내용을 즉시 로그와, DB에 기록한다.

    Undo : 커밋 이전에 데이터를 갱신하기 때문에 문제시 Undo 작업을 수행한다.

    Redo : 커밋 이전 데이터 변경 값이 디스크에 잘 들어갔는지 모르기 때문에 Redo 연산 또한 필요하다.

    [그림 6] 즉시 갱신

    체크 포인트

    회복시 로그 파일 정보를 모두 비교하며, 이미 디스크에 정상적으로 반영된 부분에 Undo, Redo 작업을 수행했다. 이러한 불필요한 연산을 줄이고자 Check Point가 도입됬다. 즉, 체크 포인트 이전에 수행된 결과는 신경쓰지 않고 이후 값들에 대해 Undo, Redo 작업을 수행한다.

    아래 사진과 같이, 에러가 나왔을 때 커밋을 이미 했다면 체크포인트 이후에 Redo 작업을, 커밋을 수행하지 않았다면 체크 포인트 이후에 Undo 작업을 수행한다.

    [그림 7] 체크 포인트

     

    그림자 페이징 기법

    트랜잭션이 실행되는 동안 로그를 사용하지 않고 두개의 페이지 테이블을 이용한다. 트랜잭션에 의해 변경된 데이터는 현재 페이지 테이블에만 변경이된다. 만약 중간에 문제가 생겨 UNDO 작업을 수행한다면 그림자 페이지 테이블을 참조한다. 로그 레코드를 유지할 필요는 없지만, 많은 페이지의 I/O 연산 작업으로 트랜잭션 처리 비용이 많다.

    [그림 8] 그림자 페이징 기법

    'Database' 카테고리의 다른 글

    Chapter 6. Partitioning  (0) 2021.02.18
    Chapter 5. Index  (0) 2021.02.18
    Chapter 4. Normalization  (0) 2021.02.18
    Chapter 3. Join  (0) 2021.02.18
    Chapter 2. SQL과 NoSQL  (0) 2021.02.17
Designed by Tistory.