[데이터베이스] #12. 트랜잭션

bien·2023년 5월 27일
0

데이터베이스

목록 보기
10/17

DBMS가 내가 명령한 처리를 제대로 시행못하고, 엉뚱한 결과를 출력한다면, 그 기능과 확장성을 떠나서 사용하기 힘든 DBMS일 것이다. 사용자의 요구를 "정확하게" 수행하기 위해서 DBMS는 어떤 기능을 가지고 있을까??

01. 트랜잭션의 이해

트랜잭션의 개념

데이터 동시 접근의 문제

- 동일 데이터에 다수 사용자의 접근 허용 시 일관성이 훼손

고객 A가 500원을 출금하는 것과, 고객 B가 해당 계좌에 1000원을 입금하는 것이 동시에 이뤄진다면, 하나의 계좌에 2개의 다른 금액 상태가 발생한다. 하나의 데이터에 여러 작업이 동시에 수행될때 데이터의 일관성에 훼손이 발생한다.

DBMS는 다수의 사용자가 동시에 여러 형태의 데이터를 사용하기위해 모아놓은 데이터의 집합. DBMS는 어떻게 데이터의 일관성 훼손을 예방하면서 동일 데이터 요청을 처리할까?

트랜잭션의 개념

  1. 데이터베이스를 조작하기 위한 하나의 논리적 단위를 이루는 일련의 연산의 집합
    • 예) 예금 인출
      • 작업 단위: 예금 1000원 인출
      • 일련의 연산: Read(A), A=A-1000, Write(A)
        (논리적 작업은 하나지만, DBMS는 여러개의 작업을 거처야 한다.)
  2. 데이터베이스를 사용하여 처리하는 작업을 하나의 묶음으로 인식하여 묶음 단위로 실행되도록 정의한 개념

트랜잭션의 특징

  1. 다수의 연산으로 구성된 트랜잭션이 사용자에게 단일작업처럼 다뤄지도록 ACID 특징을 준수
    (DBMS는 항상 ACID 특징을 준수해야 한다!)

  2. ACID 특성

    • 원자성(atomicity): 하나의 트랜잭션에 포함된 모든 연산은 완전히 수행되거나 전혀 수행되지 않음.
    • 일관성(consistency): 특정 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지
      트랜잭션이 끝난 이후에는 시행전과 동일하게 일관성이 유지되어야 한다.
    • 고립성(isolation): 특정 트랜잭션이 데이터베이스를 갱신하는 동안 다른 트랜잭션에 의해 방해받지 않음.
      하나의 트랜잭션은 자기 혼자서만 시행되어야 한다. 하나의 트랜잭션이 시행되고 있는데, 다른 작업이 자신을 멈추고 시행되지 않는다. 하나의 트랜잭션은 다른 트랜잭션에 의해 절대로 방해받지 않는다.
    • 지속성(durability): 완료된 트랜잭션의 결과는 어떠한 시스템의 장애에도 데이터베이스에 반영되어야 함.

트랜잭션 읽기와 쓰기

  1. 트랜잭션의 두 연산

    • read(X): 데이터베이스에서 데이터 X를 읽고, 트랜잭션이 실행되는 메모리의 변수 X에 값을 저장하는 연산
      트랜잭션이 시작되면 자동적으로 메모리에 트랜잭션을 위한 위치가 배정됨. 해당 위치에 변수 X의 값을 넣어주는 연산이 read
    • write(X): 트랜잭션이 실행되는 메모리에 있는 변수 X의 값을 데이터베이스에 저장하는 연산
      반대로, 트랜잭션이 확보하고 있는 메모리 공간의 변수 x의 값을 다시 데이터베이스의 X에다가 저장하는 연산이 write
  2. 계좌 A에서 B로 1,000원을 이체하는 트랜잭션

ACID 특성 유지

원자성(atomicity)

하나의 트랜잭션에 포함된 모든 연산은 완전히 수행되거나 전혀 수행되지 않음.

작업이 쭉 시행되다가 DBMS나 H/W에 오류로 A값에 1000원을 뺀 상태에서 기능이 정지되었으면, 이 상태에서 멈춰있을까? 아니다. 원자성에 의해 작업 처리 이전으로 되돌려보내는 과정을 가친다.

일관성(consistency)

특정 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지

제일 처음 A와 B의 계좌에 각각 10000원씩 총 20000이 있었다. 트랜잭션을 시행하면서 A에서 1000원이 빠져서 일관성이 훼손된다. 그러나 쭉 작업이 처리되어 B에 1000원을 추가하여 A는 9000원, B는 11000원이 되어 다시 전체 계좌는 20000원이 된다. 트랜잭션 시행동안은 일관성이 훼손되었으나, 트랜잭션이 끝난 이후에는 최종 금액의 일관성을 원복한다.

고립성(isolation)

특정 트랜잭션이 데이터베이스를 갱신하는 동안 다른 트랜잭션에 의해 방해받지 않음

처리되고 있는데, 갑자기 또다른 트랜잭션이 끼어들어서 A의 값을 출력하려고 한다. 아직 A의 값을 저장하지 않았으므로 또 다른 사용자가 A의 계좌를 읽으면 10000원으로 출력된다. 그러나 현재 A의 계좌는 천원을 제거한 9000원인 상태이다. 이런 불상사를 예방하기 위해, 하나의 트랜잭션이 처리되는 동안은, 다른 트랜잭션이 작업을 중단할 수 없다.

지속성(durability)

완료된 트랜잭션의 결과는 어떠한 시스템의 장애에도 데이터베이스에 반영이 되어야 함

트랜잭션이 끝나고 나면 A는 9000원, B는 11000원으로 종료된다. 정상적으로 작업이 끝나고 나면, 해당값이 영구적으로 지속되어야 한다. 만약 트랜잭션이 모두 끝난 이후, 하드디스크의 물리적 오류로 해당 데이터가 손상되더라도, DBMS는 지속성을 만족시키기위해 또 다른 곳에서 데이터를 불러와 이 최종값을 다시 원복시키는 과정을 수행한다.

트랜잭션의 연산자

  1. 트랜잭션의 연산
    • Read(X): 데이터베이스에서 데이터 X를 읽고, 트랜잭션이 실행되는 메모리의 변수 X에 값을 저장하는 연산
    • Write(X): 트랜잭션이 실행되는 메모리에 있는 변수 X의 값을 데이터베이스에 저장하는 연산
  2. 트랜잭션 실행의 연산
    • Commit: 트랜잭션 연산에 의해 데이터 항목의 값을 데이터베이스에 반영시키고 지속성을 확보하는 연산 (like 완료버튼)
    • Rollback: 트랜잭션이 중단되기 이전까지 수해한 연산에 의해 갱신된 모든 데이터 항목의 값을

트랜잭션의 5가지 상태 변화

  1. 동작: 트랜잭션이 시작을 준비 또는 실행중인 단계
    나 이 트랜잭션 시작한다?하고 알리면 DBMS가 OK!하고 준비하는 단계
  2. 부분 커밋: 마지막 연산을 실행한 직후의 상태
    실제 트랜잭션의 연산자를 다 수행하고, 그 처리결과가 트랜잭션이 확보한 메모리공간에만 남아있는다. 이 결과가 아직 DBMS에 반영되지 않고 트랜잭션 메모리에만 처리 결과가 남아있는 상태.
  3. 커밋: 모든 실행이 성공적으로 완료된 후의 상태
    메모리의 모든 처리결과가 실제 DBMS에 반영된 상태
  4. 실패: 실행이 정상적으로 진행될 수 없는 상태
    트랜잭션이 연산 시행하려고 하는데, S/W 혹은 H/W의 오류로 처리할 수 없는 실패상태.
  5. 중단: 실행 상태로 롤백되고 시작 이전의 상태로 환원된 상태
    실패상태가 되면 중단상태가 되어, 지금까지 시행되었던 여러 명령들을 다 Rollback(원복)하여 되돌리고 난 상태.

실제 데이터가 어디에 있느냐에 따라 5가지 상태변화를 갖고 있다. 이 5가지 상태변화를 정확하게 파악하고 있어야 데이터가 어디까지 반영되고 반영되지 않았는지, 처리의 재수행 필요 여부를 확인할 수 있으므로 5단계를 정확하게 이해하고 있어야 한다.


02. 트랜잭션의 동시성

동시성 고려

정보를 동시에 다루려 드니까 문제가 되는거잖아. 그냥 데이터를 동시에 안다루면 다 끝날 문재인데, DBMS는 왜 계속 데이터 동시 사용을 고려하려고 하는걸까?
=> 처음부터 동시에 쓰는게 개발 목적. 대기시간 감소 (= 사용자 만족도신뢰도 향상)

  1. DBMS는 다수의 사용자가 데이터베이스를 공용으로 사용하기 위한 목적으로 도입
  2. 트랜잭션 동시 실행의 이점
    • 트랜잭션 처리율과 자원 이용률을 향상
    • 트랜잭션의 대기 시간을 감소
  3. 다중 사용자 환경에서 트랜잭션의 동시 실행으로 데이터 갱신 시, 일관성 훼손 문제가 발생
  4. 동시성 제어(concurrency control)
    • 다수의 트랜잭션이 성공적으로 동시에 실행되어도 일관성을 유지할 수 있도록 지원하는 기법

서로 다른 데이터면 동시에 처리되어도 괜찮은거 아닌가?

적용 트랜잭션

  1. A와 B에 각각 10,000과 20,000원 잔액
  2. T: 1000원을 계좌 A에서 B로 이체
  3. T: 계좌 A의 잔고에서 20%를 B로 이체

어떻게 동시에 처리하면서, 동시에 처리하지 않은것과 같은 효과를 보여줄 수 있을까?

동시에 처리하려고 여러 요청이 한번에 들어오면, DBMS가 요청을 뒤죽박죽 늘어놓는 것이 아니라, 요청이 들어온 순서대로 쭉 늘어놓고 스케줄을 만든다. 그리고 이 스케줄을 보면서, 동시에 처리가 가능한지 판단해본다.

**스케줄(schedule)

  • 다수의 트랜잭션에 포함된 연산의 실행 순서를 명시한 것.

직렬/병렬 스케줄

직렬 스케줄

  1. T와 T이 순차적으로 실행되는 스케줄

직렬 스케줄

  • 각 트랜잭션에 속한 모든 연산이 순차적으로 실행되는 스케줄

병렬 스케줄

  1. T0과 T1의 비순차적 실행되는 스케줄

스케줄 3은 병렬 스케줄이지만 일관성이 훼손되지 않았다. 그에 해 케줄 4는 Read, Write를 뒤죽박죽 섞어가며 시행해 최종 금액이 A는 9000원, B는 22000원이 되어버린다. 일관성이 유지되지 않는다.

병렬 스케줄

  • 하나의 트랜잭션이 완료되기 전에 다른 트랜잭션이 실행되는 스케줄
    병렬 스케줄의 순서로 연산을 수행할 경우 일관성의 훼손이 발생 가능

직렬 가능 스케줄

이런 병렬 스케줄은 직렬로 변경해야 한다. 이를 위해 병렬 스케줄 중 일관성을 훼손시키는 스케줄을 파악할 수 있어야 한다!

직렬 가능 스케줄

  • 복수개의 트랜잭션이 동시에 수행된 결과가 직렬 스케줄의 결과와 동일한 스케줄

직렬 가능 스케줄의 정의

  1. 트랜잭션 간 연산 순서를 교환하여 트랜잭션을 직렬 스케줄과 동등하게 변환이 가능한 스케줄
  2. 사용된 Read와 Write 연산 교환 시 상황에 따라 실행 결과에 일관성이 훼손되는 현상(충돌) 이 발생
  3. 연산순서의 교환(단, Ii는 Ti의 연산)

트랜잭션의 연산자 자체가 read와 write밖에 없음. 2개의 교환에는 4개의 경우의 수 밖에 없음. 그 중, 충돌이 발생하지 않는 것은 read-read 교환밖에 없음. 연산자에 하나의 write라도 있으면 교환을 하면 안됨.

충돌 동등/ 충돌 직렬성

충돌 동등

  1. 특정 스케줄 s에서 충돌이 일어나지 않는 연산의 순서를 바꿔 스케줄 S'으로 변환이 가능한 상태

"동일한 데이터(A)"를 읽고 있을때 write의 변화가 있으면 충돌이 발생"한다.

Write(A) - Read(B) 서로 다른 데이터의 읽고 쓰기 이므로 교환을 해도 상관없다.

Write(A) - Write(B) 서로 다른 데이터를 다루고 있으므로 교환해도 상관없다.

연산의 순서를 교환해 만들어진 결과이나, 데이터의 최종 결과는 교환 이전과 동일할때, 이를 충돌 동등이라 한다.

충돌 직렬성

  1. 순서 교환이 가능한 연산을 교환하여 직렬 스케줄의 연산과 동등하게 변환이 가능한 스케줄.

충돌 동등은 유지한채 스케줄을 교환할 수 있다면, 이를 충돌 직렬성을 확보했다고 얘기한다.

스케줄 5번: 병렬 스케줄이지만 일관성이 훼손되지 않음. 충돌 직렬성을 가지고 있어 충돌 없이 직렬스케줄로 변환이 가능하므로 일관성에 훼손이 없었던 것.

스케줄 4번: 아무리 순서를 바꿔도 직렬 스케줄을 바꿀 수 없음. 충돌 직렬성을 확보하고 있지 못하기때문에 일관성이 훼손된 결과가 만들어 짐.


03. 트랜잭션의 회북

회복의 개념

  1. 원자성을 보장하기 위해 트랜잭션 실패 시 실행된 모든 연산을 실행 이전 상태로 복원하는 개념

  2. 회복 불가능한 스케줄

    • T6가 T5가 기록한 A를 읽고 커밋한 상태
    • 커밋한 T6는 롤백 불가능

Read(B)과정에서 실패가 발생해 rollback을 시행해야 하는 상황. 원복을 위해서 A에 쓴 값을 취소시켜야 하는데, T6에 Read(A) 후 commit한 상황이 문제가 된다. A의 값이 9000원임을 알려줬는데, 다시 원복시켜 만원으로 돌아간다면 T6에서 읽은 값은 잘못된 값. 그러나 이미 commit을 시켰으므로 값을 되돌리는 것은 지속성을 어긴다. 이 상황은, 회복이 불가능한 스케줄이 되었다.

모든 트랜잭션, 스케줄은 실패가 가능하므로 회복이 가능해야 한다. 이런식으로 회복이 불가능한 스케줄이 생기기 시작하면 데이터베이스의 일관성이 유지되지 못하므로 정확한 데이터를 가지고 있다 할 수 없다.

회복 가능한 스케줄

  1. Ti와 Tj에 대해 Ti가 기록한 데이터를 Tj가 읽을 때, Ti의 커밋이 Tj보다 먼저 나타나는 스케줄
  2. 연쇄적 롤백 유발 가능
    • T7의 롤백으로 인하여 연쇄적으로 다른 트랜잭션도 롤백 되는 현상

T7에서 abort라는 실패가 발생하면, 아직 T8, T9에서 commit이 없으므로 모두 rollback할 수 있다. 다만 연쇄적 롤백으로 인하여 하나의 트랜잭션 실패로 인해 다수의 트랜잭션이 모두 회복 연산을 시행해야한다는 부작용이 있다.

비연쇄적 스케줄

따라서 회복 가능하면서도, 비연쇄적인 스케줄을 만드는 것이 중요하다!

1.연쇄적 롤백으로 발생할 수 있는 대량의 회복 연산을 방지하기 위해 연쇄적이지 않은 스케줄로 구성된 스케줄
2. Ti가 기록한 데이터를 읽을 때 Ti의 커밋이 Tj의 읽기 연산보다 먼저 나타나는 스케줄



음.. 어려울게 없어 보이는데 막상 공부하면서 막막한 부분이 많았다. 근데 진짜로 어렵게 생각할 필요 없을거 같다. 복잡하게 생각할 것 없이, 마지막 그림을 최종 정답으로 생각하면 되지 않을까. commit하고 다음 트랜잭션이 read하는.. 방식으로....

profile
Good Luck!

0개의 댓글