트랜잭션, ACID, 트랜잭션 연산과 상태

Jin Hur·2022년 5월 26일
0

데이터베이스

목록 보기
10/12

reference: "데이터베이스 개론" / 김연희 / 한빛아카데미

트랜잭션

트랜잭션은 하나의 작업을 수행하기 위해 필요한 DB의 연산들을 모아놓은 것으로, DB에서 논리적인 작업의 단위가 된다.
트랜잭션은 장애가 발생했을 때 데이터를 복구하는 작업의 단위도 된다.
일반적으로 DB 연산은 SQL문으로 표현되므로 작업 수행에 필요한 SQL 문들의 집합으로 이해해도 좋다.

트랜잭션이란 것을 관리함으로써 DB의 '회복'과 '병행 제어'가 가능해져
DBMS의 '회복', '병행 제어' 기능을 통해 트랜잭션 관리가 가져야 할 ACID 특성(원자성/일관성/고립성/지속성 보장)을 만족시키며,
결과적으로 DB가 일관된 상태를 유지할 수 있게 된다.

DBMS의 트랜잭션 관리자

  • DB에 접근하는 과정에서 사용자의 접근 권한이 유효한지 검사
  • DB 무결성을 유지를 위한 제약조건 위반 여부를 확인
  • 회복과 병행 수행 작업을 담당하여 DB가 일관된 상태를 유지하도록 함

ex) 계좌이체 트랜잭션

인터넷 뱅킹을 통해 계좌이체 작업을 완벽하게 수행하기 위해 2개의 DB 연산을 처리해야 한다면, 계좌이체 트랜잭션은 2개의 연산으로 구성할 수 있다.

계좌이체 트랜잭션은 2개의 UPDATE 문으로 구성되어 있다. 그림에서 볼 수 있듯이 성호의 계좌에서 5,000을 감소시키는 UPDATE 문과, 은경이의 계좌에 5,000원을 증가시키는 UPDATE 문이다.

두 UPDATE 문을 처리하는 순서는 중요하지 않지만, 둘 다 모두 정상적으로 실행되어야 한다.

만약 첫 번째 UPDATE문이 실행되고 시스템 장애가 발생하여 두 번째 UPDATE문이 실행되지 않으면, 모순된 상황이 발생한다. 이러한 모순된 상황이 발생하지 않도록 다음과 같은 절차를 밟는다.

=> (1) 두 번째 UPDATE 문을 실행하여 트랜잭션의 모든 UPDATE 문이 정상적으로 실행되도록 한다.
또는
=> (2) 첫 번째 UPDATE 문 실행을 취소하여 DB의 트랜잭션 작업 전의 원래 상태로 되돌린다.

ex) 상품주문 트랜잭션

인터넷 쇼핑몰에서 apple이라는 아이디의 고객이 p01 제품을 10개 주문하는 작업을 처리하기 위해 필요한 SQL 문들로 구성된 상품주문 트랜잭션의 예이다.

상품주문 트랜잭션은 INSERT 문과 UPDATE 문으로 구성되어 있다. 새로운 주문 내역을 주문 테이블에 삽입하는 INSERT 문과 제품의 재고량을 주문한 수량만큼 감소시키는 UPDATE 문이 필요하다. 마찬가지로 INSERT 문과 UPDATE 문이 모두 완전하게 처리되어야 상품주문 트랜잭션이 성공적으로 수행된 것이며, 어느 하나라도 처리 중 오류가 발생하면 모든 명령문이 실행되도록 하거나, 모든 명령문의 실행을 취소하고 트랜잭션 작업 전의 DB 상태로 돌아가도록 해야 한다.


정리

정리하자면, 트랜잭션의 모든 명령문이 완벽하게 처리되거나 하나도 처리되지 않아야 DB가 모순이 없는 일관된 상태를 유지할 수 있다. (All or Nothing)
트랜잭션은 DB에 장애가 발생했을 때 복구 작업을 수행하거나, 다수의 사용자가 동시에 사용할 수 있도록 제어 작업을 하는 데 중요한 단위로 사용된다.
그러므로 DB의 "무결성"과 "일관성"을 보장하려면 작업을 수행하는 데 필요한 연산들을 하나의 트랜잭션으로 제대로 정의하고 관리해야 한다.

일반적으로 DB를 변경하는 INSERT / DELETE / UPDATE 문의 실행을 트랜잭션으로 관리한다.


트랜잭션 관리가 만족해야 할 특성: ACID

트랜잭션이 성공적으로 처리되어 DB의 무결성과 일관성을 보장하려면 트랜잭션 관리는 다음 네 가지 특성을 반드시 만족해야 한다.

source: http://utk-unm.blogspot.com/2016/08/acid.html

source: https://joosjuliet.github.io/tcl/

1. 원자성(atomicity)

DBMS의 '회복 기능' 필요

트랜잭션의 원자성은 트랜잭션을 구성하는 연산들이 모두 정상적으로 실행되거나, 하나도 실행되지 않아야 한다는 'all-or-nothing' 방식을 의미한다.
만약 트랜잭션을 수행하다 장애가 발생하여 작업을 완료하지 못하였다면 지금까지 실행한 연산들 모두 처리를 취소하고 DB를 트랜잭션 작업 전의 상태로 되돌려 트랜잭션의 원자성을 보장해야 한다.

트랜잭션의 원자성을 보장하려면, 이처럼 장애가 발생하였을 때 DB의 원래 상태로 복구하는 회복 기능이 필요하다.

2. 일관성(consistency)

DBMS의 '병행 제어 기능' 필요

트랜잭션의 일관성은 트랜잭션이 수행된 후에도 DB가 일관성을 유지해야 함을 의미한다. 즉, 트랜잭션이 수행되기 전에 DB가 일관된 상태였다면 트랜잭션의 수행이 완료된 후에도 결과를 반영한 DB도 또 다른 일관된 상태가 되어야 한다는 의미이다.
트랜잭션이 수행되는 과정 중에는 DB가 일시적으로 일관된 상태가 아닐 수 있지만 트랜잭션의 수행이 성공적으로 완료된 후에는 DB가 일관된 상태를 유지해야 한다. 트랜잭션 수행 이 후 데이터 불일치가 발생하면 안된다는 뜻이다.

위 두번째 그림을 보면 계좌이체 트랜잭션이 수행된 후에 성호의 계좌 잔액은 5,000원으로 감소하였지만 은경의 계좌 잔액이 0으로 잔액의 합계가 5,000원이 되었다. 이 경우 DB는 5,000이 사라진 모순된 상태가 되어 일관성을 만족하지 않으므로 트랜잭션의 수행이 성공적으로 완료되었다 볼 수 없다.

3. 격리성(isolation)

DBMS의 '병행 제어 기능' 필요

트랜잭션의 격리성은 고립성이라고도 하는데, 현재 수행 중인 트랜잭션이 완료될 때까지 트랜잭션이 생성한 중간 연산 결과에 다른 다른 트랜잭션들이 접근할 수 없음을 의미한다. 일반적으로 DB 시스템에서는 여러 트랜잭션이 동시에 수행되지만 각 트랜잭션이 트랜잭션이 독립적으로 수행될 수 있도록 다른 트랜잭션의 중간 연산 결과에 서로 접근하지 못하게 한다.

위 그림 중 계좌이체 트랜잭션에서 첫 번째 연산(성호 계좌에서 5,000원 감소)이 실행된 후 두 번째 연산(은경 계좌에 5,000원 증가)이 실행되기 전에는 DB는 일시적으로 일관되지 못한 상태가 된다. 이때 계좌입금 트랜잭션이 은경이의 계좌에 1,000을 입금하고, 은경이의 계좌 잔액을 여전히 0원으로 알고 있는 계좌이체 트랜잭션이 두 번째 연산을 실행하면 모순된 상태가 발생하여 DB의 일관성을 보장하기 어렵게 될 수 있다.

따라서 하나의 트랜잭션이 수행 과정 중 생성되는 중간 연산의 결과에 다른 트랜잭션이 접근할 수 없도록 하여 트랜잭션의 격리성을 보장해야 한다.

4. 지속성(durability)

DBMS의 '회복 기능' 필요

트랜잭션의 지속성은 영속성이라고도 하는데 트랜잭션이 성공적으로 완료된 후 DB에 반영한 수행 결과는 어떠한 경우에도 손실되지 않고 영구적이어야 함을 의미한다. 즉, 시스템에 장애가 발생하더라도 트랜잭션 작업 결과는 없어지지 않고 DB에 그대로 남아있어야 한다는 의미이다. 트랜잭션의 지속성을 보장하려면 시스템에 장애가 발생했을 때 DB를 원래 상태로 복구하는 회복 기능이 필요하다.

(추가 설명)
지속성: "성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미"

지속성 유지를 위해선 하나의 트랜잭션이 성공적으로 수행되었다면, 해당 트랜잭션에 대한 로그가 남아야한다.
전형적으로 모든 트랜잭션은 로그로 남고, 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 committed 상태로 간주될 수 있다.


트랜잭션의 특성을 지원하는 DBMS

source: https://incheol-jung.gitbook.io/docs/q-and-a/db/isolation-level

트랜잭션의 네 가지 특성을 보장하기 위해 DBMS는 이를 지원하는 기능들을 제공한다.

  • 원자성 보장 <- DBMS의 회복 기능
  • 일관성 보장 <- DBMS의 병행 제어 기능
  • 격리성 보장 <- DBMS의 병행 제어 기능
  • 지속성 보장 <- DBMS의 회복 기능

트랜잭션의 연산

트랜잭션의 수행과 관련하여 주로 사용되는 연산에는 작업 완료를 의미하는 commit 연산작업 취소를 의미하는 rollback 연산이 있다.

  • commit 연산: 트랜잭션이 성공적으로 수행되었음을 선언(작업 완료)
    : 트랜잭션의 수행이 성공적으로 완료되었음을 선언하는 연산이다. commit 연산이 실행된 후에야 트랜잭션의 수행 결과가 DB에 반영되어 DB가 일관된 상태를 지속적으로 유지하게 된다.

  • rollback 연산: 트랜잭션이 수행을 실패했음을 선언(작업 취소)
    : 트랜잭션의 수행이 실패했음을 선언하는 연산이다. rollback 연산이 실행되면 트랜잭션이 지금까지 실행한 연산의 결과가 취소되고 트랜잭션이 수행되기 전의 상태로 다시 돌아간다.

source: https://rebro.kr/162


트랜잭션 상태

source: https://rebro.kr/162

트랜잭션은 다섯 가지 상태 중 하나의 속하게 된다.

  • 활동(활성화) 상태: 트랜잭션이 수행을 시작한 상태
    : 트랜잭션이 수행을 시작하여 현재 수행 중인 상태를 '활동 상태'라 한다. 활동 상태인 트랜잭션은 상황에 따라 부분 완료 상태나 실패 상태가 된다.

  • 부분 완료 상태: 트랜잭션이 마지막 연산을 처리하고 난 후 상태
    : 트랜잭션의 모든 연산을 처리한 상태이다. 부분 완료 상태인 트랜잭션은 모든 연산의 처리가 끝났지만 트랜잭션이 수행한 최종 결과를 DB에 아직 반영하지 않은 상태이므로, 아직은 트랜잭션의 수행이 성공적으로 완료되었다고 볼 수 없다.

  • 완료 상태: 부분 완료 상태의 트랜잭션이 "commit" 연산을 실행한 상태
    : 트랜잭션이 성공적으로 완료되어 commit 연산을 실행한 상태이다. 트랜잭션이 완료 상태가 되면 트랜잭션이 수행한 최종 결과를 DB에 반영하고, DB가 새로운 일관된 상태가 되면서 트랜잭션이 종료된다.

  • 실패 상태: 활동 상태나 부분 완료 상태에서 여러 원인들로 인해 더는 정상적인 수행이 불가능하게 된 상태
    : HW, SW의 문제나 트랜잭션 내부의 오류 등의 이유로 장애가 발생하여 트랜잭션의 수행이 중단된 상태이다.

  • 철회 상태: 실패 상태의 트랜잭션이 "rollback" 연산의 실행한 상태
    : 트랜잭션이 실패하여 rollback 연산을 실행한 상태이다. 트랜잭션이 철회 상태가 되면 지금까지 실행한 트랜잭션의 연산을 모두 취소하고 트랜잭션이 수행되기 전의 DB 상태로 되돌리면서 트랜잭션이 종료된다.

    • 철회 상태의 트랜잭션은 상황에 따라 다시 수행되거나 폐기된다.
      트랜잭션의 내부 문제가 아닌, HW, SW의 이상이나 SW 오류로 트랜잭션의 수행이 중단되고 철회 상태가 된 경우에는 철회된 트랜잭션을 다시 시작한다.
      하지만 트랜작션이 처리하려는 데이터가 DB에 존재하지 않거나 트랜잭션의 논리적 오류가 원인인 경우에는 철회된 트랜잭션을 폐기한다.

0개의 댓글