Transcation 이란

트랜잭션이란?

트랜잭션이란 질의(query)를 하나로 묶음 처리해서 만약 중간에 실행이 중단될 경우, 처음부터 다시 실행하는 Rollback을 수행하고, 오류없이 실행을 마치면 commit을 하는 실행 단위를 의미한다. 즉, 한 번 질의가 실행되면 질의가 모두 수행되거나 모두 수행되지 않는 작업 수행의 논리적 단위이다.

  • 트랜잭션은 논리적 단위이기에, DBMS의 성능은 초당 트랜잭션의 실행 수(TPS: Transaction per second)로 측정한다.

특징 (ACID)

  • 원자성(Atomicity) : 트랜잭션이 데이터베이스에 모두 반영되던지, 아니면 전혀 반영이 안되던지 하나여야 한다.
    • 해당 특징으로 오작동 시, 원인을 찾기가 쉽다.
    • 즉, All or Noting의 개념으로 작업 단위를 일부분만 실행하지 않는다는 것을 의미. UPDATE문이 여러개 인데, 그중 몇개만 실행되면 안된다.
  • 일관성(Consistency) : 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다.
    • 트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트된 데이터베이스로 트랜잭션이 진행되는 것이 아니라, 처음에 트랜잭션을 진행하기 위해 참조한 데이터베이스로 진행된다. 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것.
    • 즉, 참조하는 데이터베이스가 같고, 참조하는 데이터의 타입 같은 것이 일관성있게 같아야 한다는 느낌.
  • 독립성(=격리성)(Isolation) : 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도, 다른 트랜잭션에 끼어들 수 없다는 점을 의미한다. 하나의 특정 트랜잭션이 완료될때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.
    • 트랜잭션 수행시 다른 트랜잭션의 작업이 끼어들지 못하도록 보장하는 것.
    • 즉, 트랜잭션끼리는 서로를 간섭할 수 없다.
  • 지속성(Durability) : 지속성은 트랜잭션이 성공적으로 완료됐을 경우, 결과는 영구적으로 반영되어야 한다는 점이다.
    • 성공적으로 수행된 트랜잭션은 영원히 반영이 되는 것.
    • commit을 하면 현재 상태는 영원히 보장이 된다.

원자성 보장

트랜잭션에서 원자성은 수행하고 있는 트랜잭션에 의해 변경된 내역을 유지하면서, 이전에 commit된 상태를 임시 영역에 따로 저장함으로써 보장한다. 즉, 현재 수행하고 있는 트랜잭션에서 오류가 발생하면 현재 내역을 날려버리고 임시 영역에 저장했던 상태로 Rollback 한다는 것.
이전 데이터들이 임시로 저장되는 영역을 롤백 세그먼트(Rollback segment)라고 하며, 현재 수행하고 있는 트랜잭션에 의해 새롭게 변경되는내역을 데이터베이스 테이블이라고 한다. 원자성은 Rollback segment에 의해 보장된다.
만약 rollback을 하는데, 트랜잭션 길이가 길다면? 확실하게 오류가 발생하지 않는 부분도 다시 처음부터 작업을 수행한다. 따라서 확실한 부분에 대해서는 rollback이 되지 않도록 중간 저장 지점인 save point를 지정할 수 있다. 아마 oracle을 했다면 익숙할 수 도 있다. save point를 지정하면 rollback할 때, save point 이전은 확실하다 간주하고 그 이후부터 진행하게 된다.

일관성 보장

트랜잭선에서 일관성은 트랜잭션 수행 전, 후에 데이터 모델의 모든 제약 조건(기본키, 외래키, 도메인, 도메인 제약조건 등)을 만족하는 것을 통해 보장한다.
예를 들면, Movie와 Video 테이블이 있을 때, Video 테이블에 Movie 테이블의 primary key인 movie_id가 외래키로 존재한다하면, 만약 movie_id의 제약조건이 Movie테이블에서 변경되면, Video 테이블에서도 movie_id가 변경되어야 한다. 한쪽의 테이블에만 데이터 변경사항이 이루어지면 안되는 것이다.

그렇다면 어떻게 트랜잭션은 일관성을 보장하는가?
어떤 이벤트와 조건이 발생했을 때, 트리거(Trigger)를 통해 보장한다. 트리거는 의미에서 추론할 수 있다시피, 데이터베이스 시스템이 자동적으로 수행할 동작을 명시하는데 사용된다. 즉, 어떤 행위의 시작을 알리는 것이다.

Create OR REPLACE trigger movie_id_check
After update of movie_id on Movie
for each row
DECLARE
...
BEGIN
...
END

MOVIE 테이블에 UPDATE문이 발생하면 해당 movie_id_check라는 이벤트를 발생시키는 트리거를 생성한 예제이다.

고립성 보장

트랜잭션이 고립성을 보장하는 방법에 대해 이해하기 위해서는 병행 트랜잭션에 대해 먼저 알아야한다.

  1. 병행 처리(concurrent processiong)
    CPU가 여러 프로세스를 처리하는 것처럼, 트랜잭션에 정해진 시간을 할당해서 작업을 하다가 부여된 시간이 끝나면 다른 트랜잭션을 실행하는 방식으로 트랜잭션들을 조금씩 처리하는 것을 의미한다.
    하지만 이렇게 되다면 많은 트랜잭션들이 조금씩 처리되는 과정에서 공통된 데이터를 조작하게 되는데, 이 경우 데이터가 혼란스러워 질 가능성이 있다.

    예를 들어, A 트랜잭션에서 x라는 데이터를 100으로 설정한 후 시간이 만료되어 B 트랜잭션으로 넘어갔다고 가정한다.
    B 트랜잭션에서도 같은 x 데이터에 -50 연산을 해서 저장을 했을 때, 시간이 만료되어 다시 A 트랜잭션이 실행될 경우, x 데이터의 값은 50이 된다.
    이렇게 트랜잭션이 조금씩 수행될 때, 공통된 데이터가 다른 트랜잭션에 의해 방해되면 안된다. 이와같이 트랜잭션의 간섭이 일어날 경우 갱신분실, 오손판독, 반복불가능, 팬텀문제 등 여러 문제점이 나타날 수 있다 한다.


  2. 고립성 보장
    병행처리 과정에서 트랜잭션의 고립성이 왜 보장되어야 하는가를 알 수 있다.

    그러면 고립성을 어떻게 보장하는가?
    OS의 세마포어(semaphore)와 비슷한 개념으로 lock&excute unlock 를 통해 고립성을 보장할 수 있다.

    • 세마포어란?
      멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법.

    즉, 데이터를 읽거나 쓸 때는 문을 잠궈서 다른 트랜잭션이 접근하지 못하도록 고립성을 보장하고, 수행을 마치면 unlock을 통해 데이터를 다른 트랜잭션이 접근할 수 있도록 허용하는 방식이다.

    트랜잭션에서는 데이터를 읽을 때, 여러 트랜잭션이 읽을 수는 있도록 허용하는 shared_lock을 한다.
    즉, shared_lock은 데이터를 쓰기를 허용하지 않고 오직 일기만 허용한다.

    또한 데이터를 쓸 대는 다른 트랜잭션이 읽을 수도 쓸 수도 없도록 하는 exclusive_lock를 사용한다. 그리고 읽기, 쓰기 작업이 끝나면 unlock을 통해 다른 트랜잭션이 lock을 할 수 있도록 데이터에 대한 잠금(lock)을 풀어 준다.

    그런데 lock과 unlock를 잘못 사용하면 데드락(deadlock) 상태에 빠질 수 있다.
    모든 트랜잭션이 아무것도 수행할 수 없는 공황상태가 되는 것이다.

  3. 2PL 프로토콜(2 Phase Locking protocol)
    앞서 말한 데드락에 쉽게 걸리지 않도록, 어떠한 규칙에 의해 고립성을 보장하는 2PL 프로토콜이 연구되었다.
    2PL 프로토콜이란, 여러 트랜잭션이 공유하고 있는 데이터에 동시에 접근할 수 없도록 하기위한 목적을 가진 프로토콜인 것이다.

    이름과 같이 2가지 단계의 locking이 존재한다.
    한 가지는 상승 단계(growing phase) 이고, 다른 것은 하강 단계(shrinking phase) 이다.
    상승 단계란 read_lock, write_lock을 의미, 즉 lock단계를 의미하고, 하강 단계란 unlock를 의미한다.

    2PL 프로토콜은 상승 단계와 하강 단계가 섞이면 안된다는 것을 의미한다.
    2PL
    출처: https://victorydntmd.tistory.com/129
    하지만, 해당 프로토콜에도 데드락은 일어난다. 이를 해결하는 방법은, 해당 트랜잭션이 발생할 때, 필요한 잠금을 동시에 설정하면 해결할 수 있다. 그 외의 방법에는 교착상태 회피 방법, 탐지 방법이 있다고 한다.


  4. 지속성 보장 지속성은 커밋된 후 작업 결과가 없어지지 않고 데이터 베이스에 그대로 남아야 하는데, 해당 특징을 보장하려면 시스템에 장애가 발생하였을 때, 데이터베이스를 원래 상태로 보국하는 회복 기능이 필요하다.

트랜잭션의 상태

트랜잭션의 상태
출처 : https://www.geeksforgeeks.org/transaction-states-in-dbms/

  • 활동 상태
    트랜잭션이 수행을 시작하여, 현재 수행중인 상태.
  • 부분 완료 상태
    마지막 연산이 실행된 직후의 상태. 즉, 연산은 모두 처리한 상태이지만, 수행한 최종 결과를 데이터 베이스에는 반영하지 않은 상태.
  • 완료 상태 트랜잭션이 성공적으로 완료되어 commit 연산을 완료한 상태.
  • 실패 상태
    장애가 발생하여 수행이 중단된 상태.
  • 철회 상태
    수행이 실패하여 rollback 연산을 실행한 상태.

댓글남기기