DATABASE

[Transaction & ACID]란 무엇인가

Haksae 2022. 3. 31. 14:20

1. Transaction (트랜잭션)

 

1.1 트랜잭션의 정의

트랜잭션이란 "더이상 분할이 불가능한 업무처리의 단위" 혹은 "읽기와 쓰기를 하나의 논리적 단위로 묶는 방법"을 의미한다.
  • 위의 정의를 조금 풀어서 설명하면 다음과 같다.
    • 트랜잭션이란 질의(query)를 하나의 묶음으로 처리해서 만약 중간에 실행이 중단되었을 경우, 처음부터 다시 실행하는 Rollback을 수행하고, 오류 없이 실행을 마칠 경우 commit하는 실행 단위를 의미한다.
    • 즉, 한 번 질의가 실행되면 질의가 모두 수행되거나 모두 수행되지 않는 작업 수행의 논리적 단위이다. (all-or-nothing)
  • 트랜잭션은 작업 수행의 논리적 단위이므로, DBMS의 성능은 초당 트랜잭션의 실행 수 (TPS: Transaction per second)로 측정한다.

1.2 트랜잭션은 왜 필요한가?

  • 트랜잭션은 DB 서버에 여러 개의 클라이언트가 동시에 엑세스 하거나 응용프로그램이 갱신을 처리하는 과정에서 중단될 수 있는 경우 등 데이터 부정합을 방지하고자 할 때 사용된다.
  • 부정합이 발생하지 않으려면 프로세스를 병렬로 처리하지 않도록 하여 한번에 하나의 프로세스만 처리하도록 하면 되는데, 이는 매우 효율이 떨어진다.
  • 그렇기에, 병렬로 처리할 수 밖에 없는 상황에서 부정합을 방지하고자 트랜잭션을 사용한다.
  • 즉 위에서 말한 데이터 거래 시, all-or-nothing으로 결과를 반영하는 것이다.

 

2. 트랜잭션의 특성 (ACID)

  • 트랜잭션은 4가지 특성을 지니며, 4가지 특성의 앞 글자만 따서 ACID라고 부른다.

2.1 Atomicity (원자성)

  • 트랜잭션의 작업이 부분적으로 실행되거나 중단되지 않는 것을 보장하는 것을 뜻한다. (All or Noting)

2.2 Consistency (일관성)

  • 트랜잭션의 작업 처리 결과가 항상 일관성이 있다는 것을 뜻한다.
  • 가령, 데이터 타입이 정수형인데, 저장 후에 문자열이 되지 않는다거나
  • 트랜잭션이 진행되는 동안 데이터베이스가 변경되더라도, 처음에 트랜잭션을 진행하기 위해 참조된 데이터베이스로 진행되는 것 등을 뜻한다.

2.3 Isolation (독립성 혹은 격리성)

  • 트랜잭션 수행시 다른 트랜잭션의 작업이 끼어들지 못하도록 보장하는 것을 뜻한다.
  • 하나의 특정 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조하거나 간섭할 수 없다.

2.4 Durablility (지속성 혹은 영구성)

  • 성공적으로 수행된 트랜잭션이 영구적으로 반영되는 것을 뜻한다.

 

3. 각 특성의 보장

3.1 원자성 보장

  • 트랜잭션에서 원자성은 수행하고 있는 트랜잭션에 의해 변경된 내역을 유지하면서, 이전에 commit된 상태를 임시 영역에 따로 저장함으로써 보장한다.
  • 즉, 현재 수행하고 있던 트랜잭션에서 오류가 발생하면 현재 내역을 날려버리고, 임시 영역에 저장했던 상태로 Rollback한다.
  • 이전 데이터들이 임시로 저장되는 영역을 롤백 세그먼트(rollback segment)라고 하며, 현재 수행하고 있는 트랜잭션에 의해 새롭게 변경되는 내역을 데이터베이스 테이블이라 한다.
  • 즉, 트랜잭션의 원자성은 롤백 세그먼트에 의해 보장된다.

 

3.2. 일관성 보장

  • 트랜잭션에서 일관성은 트랜잭션 수행 전, 후에 데이터 모델의 모든 제약 조건(기본키, 외래키, 도메인, 도메인 제약 조건 등)을 만족하는 것을 통해 보장된다.
  • 트랜잭션의 일관성은 어떤 이벤트와 조건이 발생했을 때, 트리거(Trigger)를 통해 보장된다.
  • 트리거는 데이터베이스 시스템이 자동적으로 수행할 동작을 명시하는데 사용된다.

3.3. 고립성 보장

  • 고립성 보장의 선행지식으로 병행 트랜잭션에 대해 먼저 설명하겠다.

a) 병행 처리 (concurrent processing)

  • CPU가 여러 프로세스를 처리하는 것처럼, 트랜잭션에 정해진 시간을 할당해서 작업을 하다가 부여된 시간이 끝나면 다른 트랜잭션을 실행하는 방식으로 트랜잭션들을 처리하는 것을 의미한다.
  • 그러나 병렬로 처리하면 많은 트랜잭션들이 데이터를 처리하는 과정에서 공통된 데이터를 조작하게되어, 혼란을 야기시킬 수 있다.
  • 이런 방식으로 공통된 데이터가 처리되거나 간섭되면, 갱신분실, 오손판독, 반복불가능, 팬텀 문제 등 여러 문제가 발생될 수 있다.
  • 그렇기에 트랜잭션에서 고립성 보장인 필수적이다.

b) 고립성 보장

  • OS의 세마포어(semaphore)와 비슷한 개념으로 lock & excute unlock을 통해 고립성을 보장할 수 있다.
  • 즉, 데이터를 읽거나 쓸 때는 문을 잠궈서 다른 트랜잭션이 접근하지 못하도록 고립성을 보장하고, 수행을 마치면 unlock을 통해 데이터를 다른 트랜잭션이 접근할 수 있도록 허용하는 방식이다.
  • 트랜잭션에서는 데이터를 읽을 때 여러 트랜잭션이 읽을 수는 있도록 허용하는 shared_lock을 한다.
  • 또한 데이터를 쓸 때는 다른 트랜잭션이 읽을 수도 쓸 수도 없도록 하는 exclusive_lock을 사용한다.
  • 모든 읽기, 쓰기 작업이 끝나면 unlock을 통해 다른 트랜잭션이 lock을 할 수 있도록 데이터에 대한 lock을 풀어준다.
  • 유의해야할 점은 lock과 unlock을 잘못 사용하면 데드락(deadlock) 상태에 빠질 수 있다. (모든 트랜잭션이 아무 것도 수행할 수 없는 상태)

deadlock

3) 2PL 프로토콜 (2 Phase Locking Protocol)

  • 위의 데드락을 방지하기위한 프로토콜이 2PL 프로토콜이다.
  • 2PL 프로토콜은 여러 트랜잭션이 공유하고 있는 데이터에 동시에 접근하는 것을 제한하는 프로토콜이다.

 

  • 해당 프로토콜은 (1) growing phase, (2) shrinking phase 라는 2가지 단계의 locking이 존재한다.
  • growing phase란 read_lock, write_lock을 의미하고, shrinking phase란 unlock을 의미한다.

  • 2PL 프로토콜은 growing phase, shrinking phase가 섞이면 안된다는 규칙이다.
  • 즉 lock과 unlock이 번갈아 수행되지 않고, lock이 수행된 후에 unlock이 쭉 수행되어야한다는 것이다.

4) locking의 두 가지 방법

 

a) 보수적 locking (conservative locking)

  • 트랜잭션이 시작되면 모든 lock을 얻는 방식으로서, 데드락이 발생하지 않지만 병행성이 좋지 못함

b) 엄격한 lock (strict locking)

  • 트랜잭션이 commit을 만날 때까지 lock을 갖고 있다가, commit을 만날때 unlock을 하는 방식
  • 데드락이 발생하지만 병행성이 좋음
  • 일반적으로 병행성이 좋은 strict 방식을 사용

 

참고자료

https://blog.yevgnenll.me/posts/what-is-acid-about-transaction

https://inpa.tistory.com/entry/MYSQL-%F0%9F%93%9A-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98Transaction-%EC%9D%B4%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

https://chrisjune-13837.medium.com/db-transaction-%EA%B3%BC-acid%EB%9E%80-45a785403f9e