1. 트랜잭션
- DBMS에서 데이터를 다루는 논리적인 작업의 단위
- DBMS에서 장애가 일어날 때 데이터를 복구하는 작업의 단위
- DBMS에서 여러 작업이 동시에 같은 데이터를 다룰 때 작업을 서로 분리하는 단위
- All or Nothing - 트랜잭션은 전체가 수행되거나 , 전혀 수행되지 않아야 함

- 트랜잭션 수행 과정
① A 계좌(박지성)의 값을 하드디스크(데이터베이스)에서 주기억장치버퍼로 읽어온다
② B 계좌(김연아)의 값을 하드디스크(데이터베이스)에서 주기억장치버퍼로 읽어온다.
③ A 계좌(박지성)에서 10,000원을 인출한 값을 저장한다.
④ B 계좌(김연아)에 10,000원을 입금한 값을 저장한다.
⑤ A 계좌(박지성)의 값을 주기억장치버퍼에서 하드디스크(데이터베이스)에 기록한다.
⑥ B 계좌(김연아)의 값을 주기억장치버퍼에서 하드디스크(데이터베이스)에 기록한다.
- 트랜잭션의 종료(COMMIT)를 알리는 방법
- ①-②-③-④-COMMIT-⑤-⑥
- ①-②-③-④-⑤-⑥-COMMIT
DBMS는 빠른 응답성을 위해 1. 을 선택한다. DBMS는 COMMIT만 해도 트랜잭션이 끝난다고 생각한다.(부분완료) ⑤,⑥은 DBMS가 시간날때 하도 된다 하드디스크에 기록하는 것은 OS가 하는거라서 논리적인 작업은 끝났다고 생각하는 것
트랜잭션의 성질(ACID)
- 원자성(Atomicity)
트랜잭션에 포함된 작업은 전부 수행되거나 아니면 전부 수행되지않아야(all or nothing) 함
- 일관성(Consistency)
트랜잭션을 수행하기 전이나 수행한 후나 데이터베이스는 항상 일관된 상태를 유지해야 함
- 고립성(Isolation)
수행중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경중인 데이터값을 훼손하는 일이 없어야함
- 지속성(Durability)
수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장해야 함
원자성
- 트랜잭션이 원자처럼 더 이상 쪼개지지 않는 하나의 프로그램 단위로 동작해야 한다는 의미
- 일부만 수행되는 일이 없도록 전부 수행하거나 아예 수행하지 않아야(All-OR-Nothing) 함
오라클 트랜잭션 제어 명령어(TCL)

COMMIT
- 트랜잭션이 연산을 완료된 것에 COMMIT문장을 통해 트랜잭션 관리자에게 알려 주는 연산

ROLLBACK
- 트랜잭션이 행한 모든 연산을 취소시키거나 트랜잭션을 재시작하도록 함

COMMIT과 ROLLBACK의 비교

일관성
- 트랜잭션을 수행하기 전이나, 후나 데이터베이스는 항상 일관된 상태를 유지해야 함
- 일관성은 테이블 생성 시 무결성 제약조건(CREATE/ALTER 문)을 통해 명시됨

고립성
- 데이터베이스는 공유가 목적이므로 여러 트랜잭션이 동시에 수행되며,이러한 트랜잭션은 상호 존재를 모르고 독립적으로 수행됨을 의미
- 고립성을 유지하기 위해서는 트랜잭션이 변경 중인 임시 데이터를 다른 트랜잭션이 읽고 쓸 때 제어가 필요함
지속성
- 트랜잭션이 모든 작업을 수행 완료하여 데이터베이스 내에 반영했다면, 트랜잭션의 결과는 영구적으로 저장되어야 함


트랜잭션 상태도

- 활동(active)
- 트랜잭션이 Begin_transaction으로부터 실행을 시작하였거나 현재 실행 중인 상태를 의미
- 다음 상태로 부분완료나 실패 상태로 전이
- 부분 완료(partially committed)
- 트랜잭션이 마지막 명령문을 실행시킨 직후의 상태를 의미
- 다음 상태로 실패나 완료 상태로 전이
- 실패(failed)
- 트랜잭션 실행 중에 장애나 오류가 발생하여 정상적인 실행을 더 이상 할 수 없는 상태를 의미
- 다음 상태로 철회 상태로 전이
- 완료(committed)
- 트랜잭션 실행이 성공적으로 완료되어 COMMIT 연산을 수행한 상태를 의미
- 철회(aborted)
- 트랜잭션 실행에 실패하여 ROLLBACK 연산을 수행한 상태를 의미
- 철회 상태의 트랜잭션 조치 방법
| 구분 | 의미 |
| 트랜잭션 재시작 | 트랜잭션 철회의 원인이 트랜잭션 자체적인 논리적 오류가 아닌 하드웨어나 소프트웨어 오류로 중단된 경우에 사용 |
| 트랜잭션 강제 종료 | 트랜잭션 철회의 원인이 트랜잭션 내부적으로 논리적 오류가 발생하여 오류를 수정해야만 하는 상황이거나 또는 얻고자 하는 데이터가 데이터베이스 내에 존재하지 않는 경우에 사용 |
트랜잭션과 DBMS
- DBMS는 ( ) 를 유지하기 위해 ( )를 사용한다.
- (원자성) , (회복 관리자 프로그램)
- (일관성) , (동시성 제어, 무결성 제약조건)
- (고립성) , (동시성 제어)
- (지속성) , (회복 관리자 프로그램)

2. 동시성 제어
- 동시성 제어 (병행 제어 : currency control)
- 다중 사용자 환경에서 둘 이상의 트랜잭션이 동시에 수행될 때, 일관성을 해치지 않도록 트랜잭션의 데이터 접근을 적절히 제어해 주는 것
- 다중 사용자 환경을 지원하는 DBMS의 경우, 반드시 지원해야 하는 기능
- 읽기,쓰기 시나리오

트랜잭션 병행 수행 문제점
쓰기/쓰기 작업을 할 때, 무제어 병행 수행을 한다면 다음과 같은 문제가 발생한다.
이 문제들은 데이터베이스에서 절대 발생하면 안 되는 현상이다.
1.갱신 손실 2.모순성 3.연쇄 복귀
갱신 손실
- 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신 할 때 발생
- 하나의 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어써서 갱신이 무효화가 되는 것


모순성
- 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신할 때 발생
- 다른 트랜잭션들이 해당 항목 값을 갱신하는 동안, 한 트랜잭션이 두 개의 항목 값 중 어떤 것은 갱신 되기 전의 값을 읽고 , 또 다른 것은 갱신된 후의 값을 읽게 되어 데이터의 불일치가 발생하는 상황

트랜잭션 T_01을 실행시킨 시점에서 관리자는 x,y값이 1500,1000일 것이라고 생각했는데, y값이 변경되어 기대와는 다른 결과를 얻게 되었다.

연쇄 복귀
-
두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신할 때 발생
-
한 트랜잭션이 데이터를 갱신한 다음 실패하여 ROLLBACK 연산을 수행하는 과정에서, 갱신과 ROLLBACK 연산을 실행하고 있는 사이에 해당 데이터를 읽어서 사용할 때 발생할 수 있는 문제
트랜잭션 병행 수행 문제점들 모두 순차 실행 함으로써 해결되었다. (제어X,순차실행O)
간단해 보이지만 성능이 떨어진다.
성능을 위해서 동시성 제어에 대해 알아보자
트랜잭션 스케줄
- 동시성 제어
다중 사용자 환경에서 둘 이상의 트랜잭션이 동시에 접속하여 해당 연산을 수행할 때, 문제점이 전혀 발생하지 않도록 트랜잭션의 수행을 적절히 제어해 주는 것
- 트랜잭션 스케줄
데이터베이스 트랜잭션을 구성하는 연산들의 실행 순서를 의미
- 트랜잭션 스케줄의 유형
1.직렬 스케줄 2.비직렬 스케줄 3.직렬 가능 스케줄
직렬 스케줄(serial schedule)
- 트랜잭션의 연산을 모두 순차적으로 실행하는 유형을 의미
비직렬 스케줄(nonserial schedule)
- 트랜잭션 직렬 수행 순서와 상관없이 병행 수행하는 스케줄을 의미
- 결과를 보장하지 않아 사용하면 안된다! (병행 수행 문제점 발생 가능)
직렬 가능 스케줄(serializable schedule)
- 비직렬 스케줄이면서 동등한 스케줄
- 비직렬 스케줄이지만 직렬 스케줄처럼 결과를 보장할 수 있다.

락
- 개념
- 갱신 손실 문제를 해결하려면 다른 트랜잭션이 데이터를 사용하는지 여부를 알 수 있는 규칙이 필요하다.
- 데이터를 수정 중이라는 사실을 알리는 방법의 잠금장치임
- 락킹(locking)기법
- 트랜잭션들이 동일한 데이터 항목에 대해 임의적인 병행 접근을 하지 못하도록 제어하는 것
- 트랜잭션 T가 데이터항목 x에 대해 read(x)나 write(x)연산을 수행하려면, 반드시 lock(x) 연산을 수행해야만 한다.
- 트랜잭션 T가 실행한 lock(x)에 대해서는 해당 트랜잭션이 모든 실행을 종료(COMMIT)을 하기 전에 반드시 unlock(x) 연산을 수행해야만 한다.
- 트랜잭션 T가 x에 lock을 걸지 않았다면, unlock(x)을 수행시키지 못한다.
- 트랜잭션 T는 다른 트랜잭션에 의해 이미 lock이 걸려 있는 x에 대해 다시 lock(x)을 수행시키지 못한다.
- 락의 유형
- 락은 트랜잭션이 읽기를 할 때 사용하는 락인 공유락(LS,shared lock)과 읽고 쓰기를 할 때 사용하는 배타락(LX,exclusive lock)으로 나뉨
- 공유락,배타락 사용 규칙
- 데이터에 락이 걸려있지 않으면 트랜잭션은 데이터에 락을 걸 수 있다.
- 트랜잭션이 데이터 X를 읽기만 한 경우 LS(X)를 요청하고, 읽거나 쓰기를 할 경우 LX(X)를 요청한다.
- 다른 트랜잭션이 데이터에 LS(X)를 걸어둔 경우, LS(X)의 요청은 허용하고, LX(X)는 허용하지 않는다.
- 다른 트랜잭션이 데이터에 LX(X)를 걸어둔 경우, LS(X)와 LX(X) 모두 허용하지 않는다.
- 트랜잭션이 락을 허용받지 못하면 대기 상태가 된다.
- 2단계 락킹

- 락을 걸고 해제하는 시점에 제한을 두지 않으면 두 개의 트랜잭션이 동시에 실행될 때 데이터의 일관성이 깨질 수 있어 이를 방지하는 방법
- 직렬 가능성을 보장
- 확장 단계(growing phase)
트랜잭션은 새로운 lock 연산만 실행할 수 있고, unlock 연산은 실행할 수 없는 단계이다.
- 축소 단계(shrinking phase)
트랜잭션은 unlock 연산만 실행할 수 있고, lock 연산은 실행할 수 없는 단계이다.
데드락
- 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대하여 락을 획득하고 상대방 데이터에 대하여 락을 요청하면 무한 대기 상태에 빠질 수 있는 현상. 교착상태라고도 함
- 일반적인 문제해결은 트랜잭션 중 하나를 강제로 중지시켜 데이터를 원래대로 돌려놓고, 나머지 트랜잭션은 정상 실행함

3. 트랜잭션 고립 수준
- 읽기,쓰기 시나리오

트랜잭션 병행 수행 문제점
읽기/쓰기 작업을 할 때, 무제어 병행 수행을 한다면 다음과 같은 문제가 발생한다.
이 문제들은 데이터베이스에서 절대 발생하면 안 되는 현상이다.
1.오손 읽기 2.반복읽기 불가능 3.유령 데이터 읽기
오손 읽기
- 읽기 작업을 하는 트랜잭션 1과 쓰기 작업을 하는 트랜잭션 2 가 있을 때,
- T1 이 T2가 작업한 중간 데이터를 읽기 때문에 생기는 문제
- T2가 ROLLBACK을 할 경우 T1은 무효가 된 데이터를 읽게되고 잘못된 결과를 도출하는 현상

반복 읽기 불가능
- 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고, 트랜잭션 1이 다시 데이터를 읽을 때 이전의 결과와 다른 결과가 나오는 현상
- 반복해서 읽었을때 일관성이 없는 것
- 오손읽기와는 달리 T2가 COMMIT을 했기 때문에 틀린 데이터는 아니다.

유령데이터 읽기
- 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고, 트랜잭션 1이 다시 데이터를 읽을 때 이전에 없던 데이터가 나타나는 현상
- 반복읽기 불가능과 비슷하지만 없던 데이터가 삽입되었다는 차이가 있다.

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

READ UNCOMMITTED(Level=0)
- 고립 수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유락을 걸지 않음
- 배타락은 갱신손실 문제 때문에 걸어야한다.
- 다른 트랜잭션에 공유락과 배타락이 걸린 데이터를 대기하지 않고 읽는다.
- 다른 트랜잭션이 COMMIT하지 않은 데이터도 읽을 수 있다.
- 그래서 오손읽기가 가능하다.
- 이 명령어는 SELECT 대상 테이블에 대해 락을 설정하지 않은 것(NOLOCK)과 같다.

READ COMMITTED(Level=1)
- 오손읽기를 피하기위해 자신의 데이터를 읽는 동안 공유락을 걸지만 트랜잭션이 끝나기 전에라도 해지 가능함
- 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행한다.
- 오라클의 기본 설정으로 아무런 설정을 하지 않으면 이 방식으로 수행된다.

REPEATABLE READ(Leavel=2)
- 자신의 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료할 때까지 유지하여 다른 트랜잭션이 자신의 데이터를 갱신할 수 없도록 함

SERIALIZABLE(Level=3)
- 고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리됨
- SELECT 대상 테이블에 미리 배타락을 설정한 것과 같은 효과를 낸다.
- 제한이 가장 심하고 데이터의 동시성도 낮다.

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


데이터베이스 시스템에서 발생할 수 있는 장애 유형
- 시스템 충돌
하드웨어 혹은 소프트웨어의 오류로 인해 주기억장치가 손실되는것
주기억장치에 상주하여 처리중인 프로그램과 데이터가 손실됨
교착상태의 발생으로 트랜잭션 작업이 수행될 수 없는 상황
- 미디어 장애 (DBMS손상)
헤드의 충돌이나 읽기 장애에 의하여 보조기억장치의 일부 데이터가 손실되는 것
보조기억장치에 저장 중인 데이터의 일부 혹은 전부가 손실됨
- 응용 소프트웨어 오류
데이터베이스에 접근하는 소프트웨어의 논리적이 오류로 트랜잭션의 수행이 실패하는 것
- 자연재해
자연재해로 시스템이 손상되는 것
- 부주의 혹은 태업
운영자,사용자의 부주의로 데이터가 손실되거나 손상을 입는 것
로그 파일
-
트랜잭션이 반영한 모든 데이터의 변경사항을 데이터베이스에 기록하기 전에 미리 기록해두는 별도의 데이터베이스
-
DBMS는 데이터베이스 손실을 방지하기 위해 트랜잭션 데이터베이스 기록을 추적하는 로그 파일을 사용
-
안전한 하드디스크에 저장되며 전원과 관계없이 기록이 남아있다.
-
로그파일에 저장된 로그의 구조
<트랜잭션번호,로그타입,데이터항목이름,수정전값,수정후값>
로그의 타입은 트랜잭션의 연산 타입 START INSERT UPDATE DELETE ABORT COMMIT 등으로 READ같은 것은 저장하지 않는다.

-
시스템 운영 중 장애가 발생하여 시스템이 다시 가동 되었을 때
- DBMS는 로그파일을 보고 트랜잭션이 종료되었는지 혹은 중단되었는지 여부를 판단
- 종료된 트랜잭션은 종료를 확정하기 위하여 재실행(REDO)을 진행
- 중단된 트랜잭션은 없던 일로 되돌리기 위해 취소(UNDO)를 진행
-
트랜잭션의 재실행(REDO)
- 로그파일에 트랜잭션 시작(START)이 있고 종료(COMMIT)가 있는 경우
- COMMIT 연산이 로그에 있다는 것은 트랜잭션이 모두 완료되었다는 의미
- 다만 변경내용이 버퍼에서 데이터베이스에 기록되지 않았을 가능성이 존재=>로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에 다시 기록하는 과정이 필요함
-
트랜잭션의 취소(UNDO)
- 로그파일에 트랜잭션의 시작(START)만 있고 종료(COMMIT)가 없는 경우
- COMMIT 연산이 로그에 보이지 않는다는 것은 트랜잭션이 완료되지 못했다는 의미
- 트랜잭션이 한 일을 모두 취소해야 함 완료하지 못했지만 버퍼의 변경 내용이 데이터베이스에 기록되어 있을 가능성이 있기 때문에 로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에서 원상복구 시켜야함
즉시 갱신, 지연 갱신
- 즉시 갱신 방법
- 버퍼(갱신 데이터)→로그 , 버퍼→데이터베이스 작업이 부분완료 전에 동시에 진행될 수 있음
- 부분완료가 되면 갱신 데이터는 로그에 기록이 끝난 상태
- 시스템 운영 시 데이터베이스 입출력 연산이 증가하는 단점이 존재
- 지연 갱신 방법
- 버퍼(갱신데이터)→로그 가 끝난 후 부분완료를 하고 버퍼→데이터베이스 작업이 진행되는 방법
- 부분완료 전에는 갱신 내용이 실제 데이터베이스에 반영이 되지 않은 상태
- 시스템 운영 시 복구 시간이 더 걸리는 단점이 존재
체크포인트를 이용한 회복
- 로그는 그대로 기록 유지하면서, 회복 관리자가 원하는 일정한 시간 간격으로 검사시점을 생성하는 것
- 회복시 많은 양의 로그를 검색하고 갱신하는 시간을 줄이기 위함
- 체크포인트가 있으면 로그를 이용한 회복 기법은 좀 더 간단해짐
- 체크포인트가 되는 순간에 다음 작업을 진행
- 주기억장치의 로그 레코드를 모두 하드디스크의 로그파일에 저장, 원래 시간 날 때 하는데, 체크포인트가 걸리면 COMMIT여부 상관없이 바로 저장
- 트랜잭션 수행 중에 변경된 버퍼 내의 내용을 하드디스크의 데이터베이스에 저장
- 체크포인트를 로그파일에 표시
- 체크포인트 이전에 COMMIT 기록이 있는 경우
- 이미 디스크에 기록되었으므로 아무 작업도 필요 없다.
- 체크포인트 이후에 COMMIT 기록이 있는 경우
- REDO(T)를 진행
- 체크포인트 이후에 변경 내용이 데이터베이스에 반영되지 않았기 때문
- 체크포인트 이후에 COMMIT 기록이 없는 경우
- 즉시 갱신 방법 이라면 UNDO(T)를 진행→버퍼의 내용이 반영됐을 수도 있어서 원상복구 시켜야함
- 지연 갱신 방법 이라면 아무 작업도 필요없다.→지연 갱신 방법은 COMMIT이전에는 버퍼의 내용을 데이터베이스에 반영하지 않기 때문

