반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags more
Archives
Today
Total
관리 메뉴

오늘부터 공부한다

트랜잭션(Transaction) 내용 추가 및 기타 본문

데이터베이스

트랜잭션(Transaction) 내용 추가 및 기타

1000hg 2019. 10. 8. 22:43
반응형

트랜잭션은 전에 내용을 정리한 적이 있었다.

하지만 내가 제대로 이해하지 못했고 부족한 내용이 많았고 설명도 이상했다.

 

1. 트랜잭션

 

1. DBMS에서 데이터를 다루는 논리적인 작업의 단위

2. DB에서 데이터를 다룰 때 장애가 일어난 경우 복구하는 작업의 단위

3. DB에서 여러 작업이 동시에 같은 데이터를 다룰 때 이 작업을 분리하는 단위

4. 트랜잭션은 전체가 수행되거나 전혀 수행되지 않아야한다.

 

우리가 데이터베이스에 삽입, 수정, 삭제등의 작업을 할 때, 여러 개의 작업들을 하나의 트랜잭션에 묶는다.

 

즉, 트랜잭션은 DBMS에서 데이터를 다루는 논리적인 작업의 단위가 된다.

 

예를들어 A계좌에서 B계좌로 돈을 이체하는 경우 A에서 돈을 빼고 B에서 돈을 더하는 2가지 Update문으로 나뉘게 된다.

 

그리고 이것들을 개별적으로 수행되는 것이 아니라 하나의 트랜잭션으로 묶이게 되며, 하나의 트랜잭션이 실행될 때 이 2개의 SQL문이 연속적으로 실행된다.

 

2개의 UPDATE문이 하나의 트랜잭션으로 묶여있다고 가정할 때 1개의 SQL만 실행되는 상황은 발생하지 않는다.

이를 All or Nothing(트랜잭션의 4번째 특징)이다.

 

 

[트랜잭션 수행 과정]

1. A계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.

 

2. B계좌의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어온다.

 

3. A 계좌에서 10000원을 인출한 값을 저장한다.

 

4. B 계좌에서 10000원을 입금한 값을 저장한다.

 

5. A 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.

 

6. B 계좌의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록한다.

 

 

 

위와 같은 트랜잭션의 수행 과정은 2가지 방법으로 나뉘어진다.

 

이때 우리는 Commit(커밋)에 대해 알아야한다.

 

Commit 이란?

 

트랜잭션의 수행이 완료됨을 트랜잭션 관리자에게 알려 주는 연산이다.

 

2가지 방법은 Commit이 어느 위치에 들어가는지에 따라 달라진다.

 

4번 까지 수행한 후 Commit 할 수 있고, 6번까지 종료한 후 Commit할 수 있다.

여기서 DBMS는 사용자에게 빠른 응답을 위해 1번 방법을 사용한다 한다.

 

 

[트랜잭션의 ACID 성질]

 

  • 원자성(Atomicity) : 트랙잭션에 포함된 작업은 전부 수행되거나 전부 수행되지 않아야한다.
  • 일관성(Consistency) : 트랜잭션을 수행하기 전이나 후나 데이터베이스는 항상 일관된 상태를 유지해야한다.
  • 고립성(Isolation) : 수행 중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경 중인 데이터 값을 훼손하지 않아야한다.
  • 지속성(Durability) : 수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장해야한다.

 

데이터베이스는 일반적인 프로그램과 다르게 4가지의 성질을 지니는데, 이를 ACID성질이라고 한다.

 

원자성은 All or Nothing의 성질로서 트랜잭션이 더 이상 쪼개지지 않는 하나의 프로그램 단위로 동작해야 한다는 의미한다. 트랜잭션이 끊기면 이후 해당 트랜잭션 어디서부터 수행되어야하는지 모르기 때문에 원자성이라는 성질을 지니게 되었다.

 

트랜잭션은 트랜잭션의 수행 전과 후에 일관된 상태를 유지해야 하고 이것을 일관성이라고 한다.

예를 들어 어떤 테이블의 기본키와 같은 속성은 유지되어야 한다는 것 또는 A에서 B로 돈 이체를 할 때 A와 B계좌의 돈의 총 합은 같아야한다는 것 등이 있다.

 

데이터 베이스는 클라이언트들이 같은 데이터를 공유하는 것이 목적이므로

여러 트랜잭션이 동시에 수행되어야한다. 이때 트랜잭션은 독립적으로 수행되어야 한다는 것이 고립성이다.

고립성을 격리성이라고 얘기하기도 하는데 이를 유지하기 위해서는 여러 트랜잭션이 동시에 접근하는 데이터에 대한 제어가 필요하다.

 

마지막으로 트랜잭션은 지속성이라는 성질을 가져야한다.

지속성트랜잭션의 성공 결과 값은 장애발생 후에도 변함없이 보관되어야한다는 것으로 트랜잭션이 정상적으로

완료(Commit)된 겅우 버퍼의 내용을 하드디스크(데이터베이스)에 확실히 기록되어야 하며, 부분 완료(Partial Commit)된 경우에는 작업을 취소(Aborted)하여야한다.

 

즉 부분 완료된 데이터는 DBMS가 책임지고 데이터베이스에 기록하는 성질이 지속성이고 영속성이라 한다.

 

 

[트랜잭션과 DBMS]

 

  • DBMS는 원자성을 유지하기 위해 회복(복구)관리자 프로그램을 작동시킴
  • DBMS는 일관성을 유지하기 위해 동시성 제어 알고리즘과 무결성 제약조건을 활용함
  • DBMS는 고립성을 유지하기 위해 동시성 제어 알고리즘을 작동시킴
  • DBMS는 지속성을 유지하기 위해 회복 관리자 프로그램을 이용함

 

어떤 트랜잭션이 실행되다가 장애에 의해 부분 완료되는 상황은 원자성과 지속성에 위배돤다.

 

그래서 DBMS는 이를 유지하기 위해 회복 관리 프로그램을 이용한다.

이는 일부만 진행된 트랜잭션을 취소시켜 원자성을 유지하고, 트랜잭션을 이전 상태로 복원 시켜 지속성을 유지시킨다.

 

또한 DBMS는 일관성과 고립성을 위해 동시에 접근하지 않도록 동시성 제어(Locking)을 활용하여 해결한다.

 

파일 시스템과 같은 경우 덮어 씌어지는 경우 일관성이 무너질 수 있고 그러한 경우는 고립성에 위배되는 경우이므로 Locking을 하여 이를 만족시킨다.

 

여기에 더해 DBMS는 잘못된 값에 대한 입력이 오면 일관성이 무너질 수 있으므로 이를 유지 시키기 위해 무결성 제약조건도 활용한다.

 

[기타 개념]

 

롤백(Rollback) : 트랜잭션이 행한 모든 연산을 취소시키거나 트랜잭션을 재시작함

 

DBMS는 일관성을 유지하기 위해 무결성 제약조건, 동시성 제어 알고리즘을 활용한다.

 

DBMS는 고립성을 유지하기 위해 동시성 제어 알고리즘을 작동시킨다.

 

DBMS는 지속성, 원자성을 유지하기 위해 회복 관리자 프로그램을 이용한다.

 

 

Rollback 연산은 트랜잭션의 실행 중에 장애가 발생한 경우에 수행된다.

 

장애가 발생한 경우 데이터베이스에 일부만 반영되어 일관되지 못한 상태를 가질 수 있으므로, 모두 취소하거나 트랜잭션을 재시작 해야한다.

 

트랜잭션은 활동(Active), 부분완료(Partially Committed), 완료(Committed), 실패(Failed), 철회(Aborted)의 5가지 상태를 가지게 된다.

 

여기서 활동(Active)은 트랜잭션이 Begin_transaction으로 부터 실행을 시작하였거나 실행중인 상태를 의미한다.

 

부분완료(Partially Committed)는 마지막 명령문을 실행시킨 직후의 상태를 의미하며 실패 또는 완료의 상태로 전이하게 된다.

 

실패(Failed)는 트랜잭션의 실행 중에 장애나 오류가 발생하여 정삭적인 실행을 할 수 없는 상태이며 Rollback 연산을 수행한 상태인 철화 상태로 전이하게 된다.

 

 

위에서 Rollback에 의해 트랜잭션이 재시작되거나 강제종료 되는 경우가 있다고 하는데,

 

철회(Aborted)의 원인이 트랜잭션 자체의 논리적 오류가 아닌 경우에는 재시작된다.

하지만 트랜잭션 철회의 원인이 트랜잭션 내부의 논리적 오류에 있는 오류를 수정해야 하는 상황이거나 얻고자 하는 데이터가 데이터베이스에 존재하지 않는 경우에는 강제종료된다.

 

2. 동시성 제어 (Currency Control)

[동시성 제어]

 

  • 다중 사용자 환경에서 둘 이상의 트랜잭션이 동시에 수행될 때 일관성을 해치지 않도록 트랜잭션의 데이터 접근 제어
  • 다중 사용자 환경을 지원하는 DBMS의 경우 반드시 지원해야 하는 기능

고립성은 상호간의 트랜잭션을 독립적으로 만들어주었다. 그런데 2개 이상의 트랜잭션이 하나의 값에 접근 하는 경우는 어떻게 될까? 2개의 트랜잭션이 모두 읽는 경우에는 문제가 발생하지 않지만, 1개의 트랜잭션은 쓰고 1개의 트랜잭션은 읽는 경우에 따라 오손 읽기. 반복불가능 읽기, 유령데이터 읽기 문제가 발생할 수 있으며, 2개의 트랜잭션이 모두 쓰기시 무제어 병행을 수행하는 경우에 갱신 손실, 모순성, 연쇄 복귀 등의 문제가 발생할 수 있다.

 

 

[갱신 손실 (LostUpdate)]

 

  • 하나의 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어씀으로써 갱신이 무효화
  • 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신(Update)할 때 발생
  • 데이터베이스에서 절대 발생하면 안되는 현상

갱신 손실은 하나의 값에 계속 덮어쓰기(Oberwrite)하여 데이터의 갱신이 무효화 되는 현상이다.

 

초기값 X = 1000이 있고, 트랜잭션 T1 = X +=300, 트랜잭션2는 T2 = X -= 500이라 할때, 동시성 제어를 해주지 않으면 1000이라는 값이 T1에 의해 1300이 된 상태에서 T2가 아직 1300으로 Write 되기 전인 X = 1000을 Read하여 1300-500이 아니라 1000-500이 수행되어 500을 갖게 되었다. T1과 T2가 순차적으로 값을 저장하여 덮어씌워지는 값의 손실을 갱신 손실이라고 한다.

 

 

[모순성(Inconsistency)]

 

  • 다른 트랜잭션들이 해당 항목 값을 갱신하는 동안 트랜잭션이 두 개의 항목 값 중 어떤 것은 갱신되기 전의 값을 읽고 다른 것은 갱신된 후의 값을 읽게 되어 데이터의 불일치가 발생하는 상황

초기값 X = 1500, Y = 1000이 있고, 트랜잭션 T1은 X와 Y를 300 증가 트랜잭션 T2는 X와Y를 3배식 증가시킬 때

 

트랜잭션 T1이 수행될 때 X와 Y는 각각 1500과 1000이 읽혀야한다. T1이 수행되면서 X만 1800으로 증가시키고

Write된 다음에 Y를 수행하는 것이 아닌 T2가 수행된다면, T2에 의해 X와 Y는 각각 5400과 3000이 되고 다시 T1의 Y가 Read해야하는 상황에서 1000이 아니라 3000이 읽혀진다. 이렇게 어떤 값은 갱신 전의 값을, 다른 값은 갱신 후의 값을 읽어 데이터가 불일치하는 것모순성이라 한다.

 

 

 

[연쇄 복귀(Cascading Rollback)]

 

  • 두 트랜잭션이 동일한 데이터 내용을 접근 할 때
  • 한 트랜잭션이 데이터를 갱신한 다음 실패하여 Rollback 연산을 수행하는 과정에서 갱신과 Rollback 연산을 실행하고 있는 사이에 해당 데이터를 읽어서 사용할 때 발생할 수 있는 문제

초기값 X = 1500, Y = 1000과 X를 300 증가시키고 Y를 200감소시키는 트랜잭션 T1과

X의 항목을 3배 증가시키는 트랜잭션 T2가 있을 때

 

T1이 X를 300 증가시키고 Write하여 1800이 된 상황에서 T2 트랜잭션이 실행되어 X를 3배하여 Write 한 후 종료되었다고 가정하자.

 

그리고 T1이 이제 Rollback 연산을 하여 1500으로 다시 돌려놓으려고 하는데 T2는 이미 해당 트랜잭션을 종료하여 롤백할 수 없는 문제가 발생한다.

 

 

[트랜잭션 스케줄(Transaction Schedule)]

 

  • 직렬 스케줄(Serial Schedule)
  • 비직렬 스케줄 (Nonserial Schedule)
  • 직렬 가능 스케줄(Serializable Schedule)

트랜잭션들은 삽입, 수정, 삭제 등과 같은 연산들로 이루어져있는데 여기서 트랜잭션 스케줄이란 그 연산들의 실행 순서를 의미한다.

 

직렬 스케줄의 경우에는 트랜잭션의 연산을 모두 순차적으로 실핸하는 유형을 의미한다.

하나의 트랜잭션이 실행되면 해당 트랜잭션이 완료되어야 다른 트랜잭션이 실행될 수 있다.

 

비직렬 스케줄은 트랜잭션의 직렬 수행 순서와 상관없이 병행 수행하는 스케줄을 의미한다.

그러므로 한 트랜잭션이 진행중인 상황에서 다른 트랜잭션이 수행될 수 있다.

 

마지막으로 직렬가능 스케줄이 있는데 직렬 스케줄과 동등한 비직렬 스케줄을 의미한다.

쉽게는 서로 영향을 주지 않는 직렬 스케줄의 비직렬적으로 수행한다는 것이다.

 

[직렬 가능 스케줄]

 

  • 두 개의 트랜잭션이 Read 연산만을 수행할 것이라면, 상호 간섭이 발생되지 않으며 연산의 순서도 중요하지 않다.
  • 두 개의 트랜잭션이 같은 데이터 항목에 접근하지 않는다면 상호 간섭이 발생되지 않으며 연산의 순서도 중요하지 않다.
  • T1이 X에 Write연산을 하고 T2가 X에 Read 또는 Write 연산을 한다면 실행 순서는 중요하다.

 

[락(Lock)]

 

  • 로킹(Locking)기법 : 트랜잭션들이 동일한 데이터 항목에 대해 임의적인 병해 접근을 하지 못하도록 제어하는 것
  • 트랜잭션 T가 실핸한 X에 대해 Read(X) or Write(X)연산을 수행하려면 반드시 lock(X) 연산을 해주어야함
  • 트랜잭션 T가 실행한 lock(X)에 대해서는 해당 트랜잭션이 종료되기 전에 반드시 unlock(X)연산을 해주어야 함
  • 트랜잭션 T는 다른 트랜잭션에 의해 이미 lock이 걸려 있는 X에 대해 lock(X)를 수행시키지 못한다
  • 트랜잭션 T가 X에 lock을 걸지 않았다면, unlock(X)를 수행시키지 못한다.

여러 개의 트랜잭션들이 하나의 데이터로 동시에 접근하려고 할 때 이를 제어해주는 도구가 Lock이다. 락은 트랜잭션이 읽기를 할 때 사용하는 공유락(LS, Shared Lock)과 읽고 쓰기를 할 때 사용하는 배타락(LX, Exclusive Lock)으로 나뉜다.

 

트랜잭션 T가 데이터 항목 X에 대하여 Shared-Lock을 설정할 경우, 트랜잭션 T는 해당 데이터 항목에 대해서만 읽을 수 있지만 기록할 수 없다.

 

그리고 Read는 서로 영향을 주지 않으므로 다른 트랜잭션도 Shared-Lock이 설정된 X에 대해서 Shared-Lock을 동시에 설정할 수 있다.

 

트랜잭션 T가 데이터 항목 X에 대하여 Exclusive-Lock을 설정할 경우. 트랜잭션 T는 해당 데이터 항목에 대해서 읽을 수 있고, 기록할 수도 있다. Write는 영향을 주는 작업이므로 다른 트랜잭션은 Exclusive-Lock을 설정한 데이터 항목 X에 대해서 어떠한 lock도 설정할 수 없다.

 

 

[공유락과 베타락을 사용하는 규칙] 

 

  • 데이터에 락이 걸려있지 않으면 트랜잭션은 데이터에 락을 걸 수 있다.
  • 트랜잭션이 데이터 X를 읽기만 할 경우 LS(X)를 요쳥하고, 읽거나 쓸 경우 LX(X)를 요쳥한다.
  • 다른 트랜잭션이 데이터에 LS(X)를 걸어둔 경우 LS(X의 요청은 허용하고 LX(X)의 요청은 허용하지 않는다.
  • 다른 트랜잭션이 데이터에 LX(X)를 걸어둔 경우, LS(X)와 LX(X) 모두 허용하지 않는다.
  • 트랜잭션이 락을 허용받지 못한다면 대기 상태가 된다.

 

[2단계 락킹(2PLP : Two-Phase Locking Protocal)]

 

  • 로킹 단위 : 로킹 기법에서 사용하는 lock 연산의 대상
  • 2단계 로킹 규약 : 락을 걸고 해제하는 시점에 제한을 두지 않으면 두 개의 트랜잭션이 동시에 실행될 때 데이터의 일관성이 깨질 수 있어서 로킹 단계를 2단계로 구분하여 이를 방지하는 방법
  • 확장 단계(Growing Phase) : 트랜잭션은 새로운 lock 연산만 할 수 있고, unlock 연산은 할 수 없는 단계
  • 축소 단계(Shrinking Phase) : 트랜잭션은 unlock 연산만 실행할 수 있고, lock 연산은 실행할 수 없는 단계

로킹 단위가 속성 -> 튜플 -> 릴레이션 -> 데이터베이스로 커질수록 구현이 용이하고 록의 수가 적어지며 제어가 간단

 

반면 로킹단위가 작을 수록 구현이 복잡하고 로크의 수가 많고 제어 기법이 복잡하여도 병행성을 높일 수 있다.

2단계 로킹 규약은 트랜잭션들이 lock하는 시간과 unlock을 하는 시간을 구분하여 수행하도록 하는 것이다.

 

2단계 로킹 규약을 사용하지 않으면 일관성이 위배되는 문제가 발생할 수 있다.

 

그래서 임의의 시간에 lock 또는 unlock을 하는 것이 아니라 확장단계와 축소 단계를 두어 이를 해결한다. 2PLPㄴ느 직렬 가능성을 보장할 수 있는 규약으로 많이 사용되지만 교착상태가 발생할 가능성이 있지만, 교착상태(deadlock)에 빠질 수 있으므로 이를 해결해 주어야한다.

 

 

 

[데드락(Deadlock)]

 

  • 데드락(Deadlock) : 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대하여 락을 획득하고 상대방 데이터에 대하여 락을 요청하면 무한 대기 상태에 빠질 수 있다.
  • 데드락은 교착상태 라고도 한다.

 

 

데이터베이스의 데드락은 운영체제의 데드락과 유사하다.

 

정의를 풀어 말하자면 공통된 자원을 이용하기 위해 여러 개의 트랜잭션이 서로 lock을 걸어주다가 무한 대기 상태에 빠지는 것을 데드락이라고 한다.

 

예를 들어 먼저 T1에서 A에 대해 락을 걸고 T2에서 B에 대해 락을 걸었다고 한다.

그리고 나서 T1에서 B에 대해 락을 걸고 T2가 A에 대해 락을 건다면 T1과 T2는 서로 A, B에 대한 락을 유지하며

무한루프에 빠지게 된다.

 

일반적으로 데드락이 발생하면 DBMS는 T1 혹은 T2 중 하나를 강제로 중지시켜 한 트랜잭션은 정상적으로 실행되며

중지된 트랜잭션에서 변경한 데이터는 원래 상태로 되돌려 놓는다.

 

 

 

3. 트랜잭션 고립 수준

 

[오손 읽기 (Dirty Read)]

 

  • 읽기 작업을 하는 트랜잭션1이 쓰기 작업을 하는 트랜잭션2가 작업한 중간 데이터를 읽기 때문에 발생하는 문제
  • 작업중인 트랜잭션 2가 작업을 Rollback한 경우 트랜잭션 1은 무효가 된 데이터를 읽게 되고 잘못한 결과를 도출함

아래의 그림과 같이 T1이 T2가 Rollback되기 전의 데이터를 읽었고, T2가 Rollback이 되면 T1이 의미가 없는 값을 갖게 되므로 문제가 발생한다. 이러한 무효가 된 데이터를 읽게 되어 발생하는 문제오손 읽기(Dirty Read)라고 한다

 

 

[반복 불가능 읽기(Non-repeatable Read)]

 

  • 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고(Update) 트랜잭션 1이 다시 한 번 데이터를 읽을 때 생기는 문제
  • 트랜잭션 1이 읽기 작업을 다시 한 번 반복할 경우 이전 결과와 다른 결과가 나오는 현상

아래의 그림과 같이 T1이 먼저 값을 읽었고, T2가 값을 갱신하였다. 그리고 T1이 다시 값을 읽으려고 하면

바로 읽은 값이 달라지는데 이를 반복불가능 읽기라고 한다.

 

 

[유령 데이터 읽기(Phantom Read)]

 

  • 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고(Insert) 트랜잭션 1이 다시 한 번 데이터를 읽을 때 생기는 문제
  • 트랜잭션 1이 읽기 작업을 반복할 경우 이전에 없었던 데이터가 나타나는 현상

아래 그림처럼 T1을 읽고, T2가 값을 삽입하고 T1이 다시 값을 읽으려고 하면

바로 전에 없었던 값이 같이 읽기게 되는데 이를 유령데이터 읽기 라고 한다.

 

[트랜잭션 고립 수준 명령어(Transaction Isolation Level Instruction)]

 

  • DBMS는 트랜잭션을 동시에 실행시키면서 락보다 좀 더 완화된 방법으로 문제를 해결하기 위해 제공하는 명령어

트랜잭션이 작업을 수행하다 보면 오손 읽기, 반복불가능 읽기, 유령데이터 읽기와 같은 문제를 직면할 수 있다.

그래서 Lock보다는 완화된 방법으로 트랜잭션을 동시에 실행시키면서, 발생하는 문제를 해결하기 위해 DBMS가 제공하는 명령어가 바로 트랜잭션 고립 수준 명령어 이다.

 

 

 

[READ UNCOMMITTED]

 

고립 수준이 Level 0으로 가장 낮은 명령어이다.

자신의 데이터에 아무런 공유락을 걸지 않는다.

 

READ UNCOMMITTED는 자신의 데이터에 아무런 공유락을 걸지 않지만 배타락은 데이터에 갱신손실 문제 때문에 걸어주어야한다. 또한 다른 트랜잭션에 공유락과 배타락이 걸린 데이터를 대기하고 있지 않고 읽는다.

 

SELECT 문을 수행하는 경우 해당 데이터에 Shared Lock이 걸리지 않는 Level이다.

 

따라서, 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은 데이터(오손데이터) B를 읽을 수 있다.

 

[READ COMMITTED]

  • 고립 수준이 level 1인 명령어로, 오손 페이지 참조를 피하기 위해 자신의 데이터를 읽는 동안 공유락을 걸지만 트렌잭션이 끝나기 전에라도 해지 가능하다.

다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행된다.

 

SQL Server가 Default로 사용하는 Isolation Level으로 SELECT 문이 수행되는 동안에 Shared Lock이 걸리게된다. 그러므로 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안에 다른 사용자는 해당 데이터에 접근할 수 없습니다.

 

[REPEATABLE READ]

 

  • 고립수준 level 2인 명령어로, 자신으 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료될 때 까지 유지하며 다른 트랜잭션이자신의 데이터를 갱신(Update)할 수 없더록 한다.

다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행된다.

 

다른 고립화 수준에 비해 데이터의 동시성(Concurrency)이 낮아 특별하지 않은 상황이라면 사용하지 않는 것이 좋다.

 

즉, 트랜잭션이 완료될 때까지 SELECT문이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다.

 

예를 들어 SELECT number FROM A WHERE BETREEN 1 and 10을 수행하였고, 이 법위에 해당하는 number가 2 or 3이 있는 경우 다른 사용자가 number 2 or 3인 행에대한 UPDATE가 불가능 하지만 나머지 범위에 대해서 행을 INSERT하는 것이 가능하다.

 

 

[SERIALIZABLE]

 

고립 수준이 Level 3 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리된다.

 

데이터 집합에 볌위를 지어 잠금을 설정할 수 있기에 다른 사용자가 데이터를 변경(UPDATE), 삽입(INSERT)하려고 할때 트랜잭션을 완벽하게 분리할 수 있다.

 

이 명령어는 가장 제한이 심하고 동시성도 낮다.

 

즉 SELECT 문이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그영역에 해당되는 데이터에 대한 수정(UPDATE) 및 입력 (INSERT)가 불가능해진다.

 

앞의 Repeatable Read의 경우에는 1에서 10 사이의 number에 대한 삽입이 가능했지만 SERIALIZABLE은 SELECT의 대상이 되는 모든 테이블에 Shared Lock을 설정하는 것과 같아서 나머지 범위에 대한 INSERT가 불가능해진다.

 

 

 

4.회복(Recovery)

 

[장애의 유형]

 

  • 트랜잭션 장애 : 트랜잭션의 실행 시 논리적인 오류로 발생할 수 있는 상황
  • 시스템 장애 : H/W 시스템 자체에서 발생할 수 있는 에러 상황
  • 미디어 장애 : 디스크 자체의 손상으로 발생할 수 있는 에러 상황

트랜잭션 실행 시 발생할 수 있는 에러 상황의 원인으로 트랜잭션 내에 잘못된 데이터 입력, 데이터의 부재, 오버플로우(Overflow), 자원의 한계 초과 요청, 어떤 수를 0으로 나누게 되는 연산 등이 있다.

 

시스템 장애는 하드웨어 자체에서 발생할 수 있는 에러로 하드웨어의 잘못된 작동으로 메인 메모리에 저장되어 있는 정보가 손실되거나 교착 상태의 발생으로 더 이상 트랜재션 작업 수행될 수 없는 상황에서 발생한다.

 

마지막으로 미디어 장애는 디스크의 손상으로 발생할 수 있는 에러로 디스크 헤드 손상이나 고장으로 인해 저장장치 내의 정보가 일부 또는 전부 손상될 수 있는 상태이다.

 

 

 

[회복 (Recovery)]

 

  • 데이터베이스를 장애가 발생했던 이전의 상태로 복구시켜 일관된 데이터베이스 상태를 만드는 것

데이터베이스를 갱신하는 과정에서 장애가 발생한 경우 회복절차를 수행하여 장애 발생 이전의 데이터베이스로 만드는 것을 회복이라고 한다.

 

회복을 위한 데이터 복사본을 만드는 방법에는 덤프(Dump)를 이용하는 방법과 로그(Log)를 이용하는 방법 2가지가 있다.

 

덤프는 가장 기본적인 기법으로 일정 주기로 원본의 데이터베이스의 모든 내용을 다른 저장장치에 복사하는 것이다.

 

로그는 변경 이전 데이터베이스를 기준으로 변경 연산이 발생할 때 마다 로그 파일을 작성하여 기록하고, 회복할 때 로그에 적힌 내용을 사용하여 복원하는 방법이다.

 

 

[로그 파일 (Log File)]

 

  • 트랜잭션이 반영한 모든 데이터의 변경사항을 데이터베이스에 기록하기 전에 미리 기록해두는 별도의 데이터베이스
  • 안전한 하드디스크에 저장되며 전원과 관계없이 기록이 존재
  • 로그의 구조 : <트랜잭션 번호, 로그의 타입, 데이터 항목 이름, 수정 전 값, 수정 후 값>
  • 로그의 타입 : START, INSERT, UPDATE, DELETE, ABORT, COMMIT 등 트랜잭션의 연산 타입

로그(log)란 트랜잭션이 데이터의 변경사항을 데이터베이스에 직접 기록하기 전에 미리 기록해두는 별도의 데이터베이스로 특정한 구조를 가지고 기록이 되며 장애 발생 시 복원을 위해서 사용된다.

 

실제로 아래와 같은 형식으로 로그기 기록된다

 

<T1, START>

<T1, UPDATE, Customer(박지성).balance, 10000, 9000>

<T1, UPDATE, Customer(김연아).balance, 10000, 11000>

<T1, COMMIT>

 

 

[로그 파일을 이용한 회복]

 

  • 데이터의 변경이 발생할 때 마다 생성되는 로그 파일을 이용하는 것
  • 데이터의 변경 기록을 저장해 둔 로그 파일을 이용하면 시스템 장애도 복구 가능

DBMS는 트랜잭션이 종료되었는지 혹은 중단되었는지 여부를 판단하여 종료된 경우에는 종료를 확정하기 위해

REDO(재실행)을 하고 중단된 경우에는 없었던 일로 되돌리기 위해 UNDO(취소)를 진행한다.

 

REDO는 장애가 발생한 후 시스템을 다시 가동 했을 때, 로그 파일에 트랜잭션의 시작(START)이 있고 종료 (COMMIT)이 있는 경우 로그를 보면서 트랜잭션이 변경한 내용을 다시 기록하는 과정이다.

 

UNDO는 장애가 발생한 후 시스템을 재가동 했을 때, 로그 파일에 트랜잭션의 시작(START)만 있고 종료(COMMIT)이 없는 경우 완료하지 못했지만, 버퍼의 변경 내용이 데이터베이스에 기록되어 있을 가능성이 있기 때문에 로그를 보면서 트랜잭션이 변경한 내용을 원상복구 시키는 과정이다.

 

REDO의 경우에는 T1에 의해 변경된 모든 데이터 항목들을 로그 파일에 있는 새로운 값으로 대체시켜야 하고 이를 T1의 첫 번째 로그 레코드 부터 진행한다.

 

하지만 UNDO는 T1에 의해 변경된 데이터 항목들을 로그파일에 있는 예전 값으로 대체하여야하고 장애가 발생한 마지막 로그부터 거꾸로 진행한다.

 

 

트랜잭션이 시작하면 변경연산에 대해서 계속 로그 파일에만 기록을 하고 실제 데이터베이스에 반영하지 않는다.

 

그러다가 부분 완료까지 성공을 하면 로그 파일을 참조하여 실제 데이터베이스 값을 변경시킨다.

 

트랜잭션이 실패한 경우에는 연산이 로그파일에만 저장이 되어있고 데이터베이스에는 반영되어있지 않았으므로 추가 작업이 필요없지만 중간에 부분 완료를 거친 후에 트랜잭션이 실패가 발생하면, 데이터베이스의 일부 기록된 내용이 있을 수 있으므로 UNDO를 해주어야한다.

 

아래의 그림 왼쪽이 트랜잭션이 성공한 경우, 오른쪽이 실패한 경우다

 

[로그 파일의 회복 방법]

 

  • 즉시 갱신(Immediate Update) : 갱신 데이터 -> 로그, 버퍼 -> 데이터베이스 작업이 부분완료 전에 동시에 진행될 수 있으며, 부분 완료가 되면 갱신 데이터는 로그에 기록이 끝난 상태
  • 지연 갱신(Deferred Update) : 갱신데이터 -> 로그가 끝난 후 부분완료를 하고 버퍼 -> 데이터베이스 작업이 진행되는 방법.

즉시 갱신은 갱신된 데이터를 로그에 기록하는 작업과 버퍼의 데이터를 데이터베이스에 옮기는 작업이 동시에 진행될 수 있으며 부분완료가 된 경우 로그에 기록이 끝난 상태인 반면

 

지연 갱신은 갱신된 데이터를 로그에 작성하는 작업이 끝난 후에야 버퍼의 데이터를 데이터베이스로 옮기는 작업이 진행될 수 있다.

 

 

[체크포인트(CheckPoint, 검사점)]

 

  • 로그는 그대로 기록을 유지하면서, 회복 관리자가 정하는 일정한 간격으로 검사 시점을 생성하는 것
  • 회복시 많은 양의 로그를 검색하고 갱신하는 시간을 줄이기 위함
  • 체크포인트가 있으면 로고를 이용한 회복 기법이 간단해짐

DBMS에서 회복을 할때 처음부터 마지막 로그 기록까지 한 번에 처리하려면 시간적으로 오래걸린다.

 

그러므로 특정 시간마다 검사해서 문제가 없으면 다음번 에러 발생 시 회복하는 시점을 앞으로 당길 수 있다.

 

그래서 체크 포인트 시점에는 다음과 같은 작업을 수행한다.

 

1. 주기억장치의 로고 레코드를 모두 하드디스크의 로그 파일에 저장한다.

2. 트랜잭션 수행 중에 변경된 버퍼 내의 내용을 하드디스크 데이터베이스에 저장한다.

3. 체크포인트를 로그파일에 다음과 같이 표시한다. <Checkpoint T_List> : T_list는 현재 수행중인 트랜잭션 리스트이다.

 

  • 체크포인트 이전에 [Commit] 기록이 있는 경우 : 아무 작업이 필요 업다.
  • 체크포인트 이후에 [Commit] 기록이 있는 경우 : REDO(T)를 진행한다.
  • 체크포인트 이후에 [Commit] 기록이 없는 경우 : 즉시 갱신 방법 사용시 : UNDO(T)진행
  • 체크포인트 이후에 [Commit] 기록이 없는 경우 : 지연 갱신 방법 사용시 : 아무런 작업이 필요없다.

 

체크포인트 이전에 Commit이 있는 경우는 로그에 체크포인트가 나타나는 시점은 이미 변경 내용이 데이터베이스에 모두 기록된 후이기에 아무런 작업이 필요없다.

 

체크포인트 이후에 Commit 기록이 있는 경우 체크포인트 이후에 변경 내용이 데이터베이스에 반영되지 않았으므로 REDO를 진행한다.

 

체크포인트 이후에 Commit 기록이 없고 즉시 갱신 방법을 사용한 경우는 갱신 데이터를 로그에 작성하는 과정과 버퍼의 내용을 데이터베이스에 기록하는 작업이 동시에 이루어지므로 버퍼의 내용이 데이터베이스에 반영됐을 수도 있기 때문에 원상 복구를 시켜야한다. (UNDO를 해야한다.)

 

하지만 체크포인트 이후에 Commit 기록이 없고 지연 갱신 방법을 사용한 경우 갱신 데이터를 로그에 작성한 후 Commit을 시작해야 버퍼의 내용을 데이터베이스에 기록하는 작업이 이루어지므로 아무런 작업도 해줄 필요가없다.

 

반응형

'데이터베이스' 카테고리의 다른 글

데이터베이스 정규화  (0) 2019.10.15
무결성 제약조건  (0) 2019.10.11
데이터베이스 모델링  (0) 2019.10.08
2단계 Commit(Two Phase Commit)  (0) 2019.10.07
트랜잭션이란?  (0) 2019.10.07