[DATABASE] 트랜잭션 (transaction)

seheo·2022년 7월 31일
0

Database

목록 보기
3/3

트랜잭션(transaction) 이란

하나의 논리적 기능을 수행하기 위한 작업의 단위로 데이터 베이스의 일관된 상태를 또 다른 일관된상태로 변환시킨다.

트랜잭션의 필요성

  • 장애(failure): 정해진 명세대로 시스템이 작동하지 않음
  • 회복(recovery): 장애가 일어났을 때 DB를 장애 발생 이전의 일관된 상태, 즉 DB 내용에 문순이 없는 상태로 복윈시키는 것

트랜잭션이 필요한 이유는 이러한 장애로 부터 데이터의 일관성을 유지하면서 안정적으로 데이터를 회복하기 위함

트랜잭션의 특성 ACID

트랜잭션이 포함된 연산이 불가분 관계로 실행되기 위해서는 ACID라는 트랜잭션의 4가지 특징을 알아야한

  • Atomicity(원자성): All of Nothing 트랜잭션은 모두 실행되거나 실행되지 않아야한다.
  • Consisency(일관성): 트랜잭션의 실행을 성공하면 언제나 데이터베이스가 일관성 있는 상태로 변환한다. 즉, 트랜잭션의 실행의 결과로 데이터베이스의 상태가 모순되지 않는다.
  • Isolation(격리성): 트랜잭션이 실행 중일때는 다른 트랜잭션이 접근할 수 없다.
  • durabiliy(영속성): 트랜잭션이 실행을 성공적으로 완료하면 그 결과는 영속적이어야 한다.

트랜잭션의 상태


1. 활동(active) 상태: 현재 수행 중
2. 부분 완료(partially committed) 상태

  • 트랜잭션의 마지막 명령문을 실행한 직후
  1. 완료(committed) 상태
  • 트랜잭셔이 완료되어 commit 연산을 실행한 상태
  • 수행결과가 DB에 반영됨을 보장함
  • DB에 반영된 것이 아님
  1. 실패(failed) 상태
  • 장애 발생으로 인한 트랜잭션 중단 상태
  1. 철회(aborted) 상태
  • 트랜잭션의 수행 실패로 rollback 연산을 수행한 상태
  • 연산을 모두 취소하고 T가 수행되기 전의 DB상태로 되돌림(Undo)
  • 상황에 따라 다시 수행(Redo)되거나 폐기

데이터 베이스 저장 연산

데이터베이이스의 장애와 회복을 이해하기 위해서는 먼전 데이터베이스 연산이 저장장치와 어떠한 관계를 맺고 있는지 알아야한다.
데이터 베이스는 실제로 디스크에 상주
트랜잭션은 메인 메모리로 데이터를 입력시켜 처리

  • 물리적 블록(physical block): 디스크에 있는 블록
  • 버퍼 블록(buffer block): 메인메모리에 있는 블록

디스크와 메인 메모리 사이의 이동 연산

  1. Input(A): 데이터 아이템이 포함되어 있는 디스크 블록 A를 메인 메모리로 이동
    • disk -> main memory
    • disk(A) = 10000이 저장되어 있는 값을 main memory(A)에 저장
  2. Output(B): 데이터 아이템이 포함 되어 있는 버퍼 블록 B를 디스크 블록에 이동시켜 기록 (영속적으로)
    • main memory -> disk
    • main memory(B)를 데이터 이동 연산하고 disk(B)에 기록

트랜잭션의 데이터 처리

  • 프로그램 변수->데이터베이스 이동
  • 데이터베이스로->프로그램 변수 이동

위 방법을 통해 데이터베이스 시스템과 상호작용

데이터 이동의 연산

  • Read(X): X의 값을 지역 변수 x의 값으로 지정한다
    • main memory에 X가 없는 경우: 트랜잭션에서 Input을 통해 disk -> main memory로 전달하여 트랜잭션의 지역변수로 초기화
    • main memory에 X가 있는 경우: main memory -> 트랜잭션 지역변수
  • Write(X): 지역변수 x의 값을 main memory X의 값으로 지정
    • main memory에 X가 없는 경우: x가 포함된 buffer block(main memory의 변수 저장단위)B에 대해 Input(Bx)를 실행한다.
      (잘 이해가 안됨 write만 사용하는 경우도 가능한건가 만약 그렇게 되면 write만 사용한 부분이 DB에 반영된다면 DB의 일관성을 깨트리지 않나? 아시는 분 답글 좀 남겨주세요)
    • main memory에 X가 있는 경우: 지역변수 x -> main memory

두 연산 모두 Input()만 실행 했기 떄문에 실제 disk에 반영되지 않는다
Output()이 실행 되어야만 write()로 변경한 지역변수가 실제 물리적 블록에 반영

트랜잭션 예시: 은행 시스템의 계좌 이체 트랜잭션

DB
A = 1000
B = 0
C = 3000
D = 0

T1: Begin_Trans
	Read(A)
    A = A - 100
    write(A)
    Read(B)
    B = B + 100
    write(B)
   End_Trans

T2: Begin_Trans
	Read(C)
    C = C - 100
    write(C)
    Read(D)
    B = B + 100
    write(D)
   End_Trans   

DB
A = 900
B = 100
C = 2900
D = 100

이 트랜잭션이 갖는 일관성 제약

  • 계좌 A와 계좌 B의 합계는 절대 변하지 않는다.
    • A에서 차감하면 B에 더 해주고, B에서 차감하면 A를 더 해준다.
    • 트랜잭션 종료 후에도 A와 B의 합계는 변하지 않아야 한다.

트랜잭션의 격리성

  • 이 트랜잭션은 따로 로킹하고 있지 않기 때문에 격리성 없음
  • 내가 T 트랜잭션을 수행하고 있을때 다른 트랙잭션T2에서 A에 접근하지 못해야된다.
  • 로킹을 통해 구현하는데 이 부분은 mingkim님 파트

트랜잭션의 원자성

Write 연산을 수행했지만 Output 연산이 실행 되지 않음

1개만 Output()연산이 수행


트랜잭션 T가 Output 연산들을 실행하는 중에 장애가 일어났다.
Output(Ba)는 수행 성공, Output(Bb) 수행 실패

  • Output(B)의 B는 Buffer임 옆의 소문자는 변수명

즉시 갱신

  • 트랜잭션 수행 중에 데이터 변경 연산의 결과를 데이터베이스에 즉시 반영 할 경우 이러한 문제가 생길 수 있다
  • 장애 발생에 대비하기 위해 데이터 변경에 관한 내용을 로그 파일에 기록
    • 변경 연산이 실행되면 로그 파일에 먼저 기록, DB는 그 뒤에 반영
    • DB 기록 순서 : 1.버퍼 2.로그 3.DB
  • 장애 발생 시점에 따라 REDO, UNDO 연산을 실행해 DB를 복구한다.

복구 연산

  • UNDO
    • 갱신된 값을 갱신 이전 상태로 되돌린다.
    • '어떻게 하면 과거의 상태로 돌아갈 수 있는지에 관한 정보'가 UNDO
  • REDO
    • Write 연산을 실행 했지만 DB에 반영 안될 경우 재실행하여 log를 토대로 DB에 기록
    • '누군가가 무엇을 했다는 정보'가 REDO 로그이다.

LOG 파일

LOG: 트랜잭션의 모든 갱신활동을 기록한다

  • 로그 파일을 통해 트랜잭션 실행 이전 상태로 복귀할 수 있다
  • 이미 완료된 트랜잭션에 대한 갱신 기록도 알 수 있다.
  • commit의 트랜잭션의 성공적으로 완료되었다는 것은 log파일을 성공적으로 작성 했다는 것이다.
    트랜잭션이 성공적으로 완료되었는 것이 DB에 반영됨을 의미하는 것이 아니다.
    하지만 log파일에 저장되었다면 Redo연산을 통해 반드시 DB에 저장됨을 보장 할 수 있다 영속성

트랜잭션 T1, T2의 log

1. <T1, start>
2. <T1, A, 1000, 900>
3. <T1, B, 0, 100>
4. <T1, commit>
5. <T2, start>
6. <T2, C, 3000, 2900>
7. <T2, D, 0, 100>
8. <T2, commit>

로그 회복 기법 - 즉시 갱신

  • <T, start>는 있지만 <T, commit>로그가 없는 상태
    트랜잭션 완료 전 장애 발생 -> undo

  • <T, start>, <T, commit>로그 모두 존재하는 상태
    트랜잭션 완료 후 장애 발생 -> redo

장애 발생

1. <T1, start>
2. <T1, A, 1000, 900>
3. <T1, B, 0, 100> <<<------장애 발생시: undo(T1) 
4. <T1, commit>
5. <T2, start>
6. <T2, C, 3000, 2900> <<<------장애 발생시: undo(T2), redo(T1)
7. <T2, D, 0, 100> 
8. <T2, commit>

Undo와 Redo 두 가지 모두 실행하는 경우 Undo실행 후 Redo를 실행하는 것이 효율적

  • Undo연산은 로그에 기록된 순서의 역순으로 실행
  • Redo연산은 로그에 기록된 순서대로 실행

이러한 Rollback연산을 통해 All of Nothing을 보장하여 트랜잭션간의 원자성을 보장한다.

요약

  1. 트랜잭션이 필요한 이유는 장애로 부터 데이터의 일관성을 유지하면서 안정적으로 데이터를 회복하기 위함
  2. 트랜젹션이 포함된 연산이 불가분 관계로 실행되기 위해서는 ACID라는 트랜잭션의 4가지 특징을 알아야한다
  3. DB Data 기록 순서: (1)버퍼 (2)로그 (3)DB
  4. 트랜잭션이 완료(commit)된다고 해서 DB에 반드시 저장되는 것은 아니다.
  • 완료 후라도 Buffered I/O에 저장되기 때문에 DB에는 언제 기록될 지 모른다.
  1. 그렇지만 log가 남아있다면 Redo연산을 통해 반드시 DB에 저장됨을 보장한다. (영속성)
  2. 트랜잭션 도중에 장애가 발생한다면 undo연산을 통해 모두 반영되지 않아야한다. (원자성)
  3. 로킹을 통해 트랜잭션에서 사용하고 있는 영역에 대해 다른 트랜잭션이 접근하지 못하게 해야한다 (격리성)
  4. 원자성을 통해 DB의 일관성을 보장해야 한다.

참고자료

저자: 이석호 / 책 제목: 데이베이스 시스템
저자: 김연희 / 책 제목: 데이터베이스 개론(2판): 기초 개념부터 빅데이터까지 / 출판사: IT CookBook

0개의 댓글