땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • ㅗ
  • I
  • 이것이 리눅스다 with Rocky Linux9
  • E
  • D

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

11장. 트랜잭션
Backend/Database

11장. 트랜잭션

2020. 12. 7. 14:07

트랜잭션

데이터베이스의 하나의 논리적인 작업 단위

 

AICD

A : 원자성 - 복구

I : 고립성(독립성) - 트랜잭션간의 간섭 배제(동시성제어)

C : 일관성 - 나중 실행 후 내용이 일관성이 있어야함 

D : 지속성 - 영구적으로 저장

 

Write의 우선 순위

1. 버퍼 //Main Memory

I/O 속도 개선책

 

2. 로그 //일련의 Disk 블럭

복구를 위한 대비책

Seek Time(접근시간)을 줄임

Log에 기록되면 실제 DB에 기록됨이 보장됨

 

3. Real DB //산재된 Disk 블럭

정상 수행시 버퍼의 내용이 기록됨

 

완료(Commit)

- 부분 완료 후 트랜잭션 결과의 영구보존이 보장

 

실패(Rollback) == 되돌리기

- 동작이나 부분완료 상태에서 더이상 진행 안 됨

- 부분완료전 장애 : Rollback

- 부분완료후 장애 

  로그에 기록 전 장애 : Rollback

  로그에 기록 후 장애 : commit

 

로그 - 회복의 핵심

- 모든 갱신 활동을 기록한 일련의 디스크

- 로그 우선 기록 규약 : Real DB보다 먼저 기록

 

> 로그 회복 기법

 

1. 즉시 갱신 회복 기법

- 즉시라 해도 즉시가 아님(버퍼 때문에)

- 당연히 로그보다 나중. commit전에 Real DB에 기록가능

- 복구 :  Undo/Redo 필요

 

#Undo : Rollback, Redo : commit

 

2. 지연 갱신 회복 기법

- commit 이후에 Real에 기록

- 복구 : Undo 불필요, Redo 필요

 

트랜잭션 시작 in 오라클

묵시적인 시작 : 데이터 변경 연산(삽삭갱), select... for update 연산

명시적인 시작 : SET TRANSACTION 문장과 함께 시작

 

종료 : commit, rollback

 

동일 세션 : DBMS를 켜서 여러개의 워크시트를 연다 ==> 동일 세션

다른 세션 : 여러개의 DBMS를 켜서 각각 세션 접속. 하나의 DBMS에 동일 계정에 대한 세션을 2개 만들어 접속,

               하나는 SQL *Plus, 다른 하나는 SQL DEVELOPER

 

Commit

변경 작업을 반영(타 세션 버퍼에 전파 + 로그에 기록 완료)

> 동일 세션

버퍼를 공유함

commit하기 전에도 변경사항 확인 가능

> 다른 세션

버퍼를 공유하지 않음

commit하기 전까지는 한 세션내의 변경내용을 다른 세션에서 확인할 수 없음

 

Rollback

변경 작업을 취소

> 동일 세션

변경 이전값으로 확인

> 다른 세션

영향이 없음

변경내용이 commit전까지는 타 세션에 반영이 안되기 때문.

 

 

<같은세션, 트랜잭션 도입 유/무>

 

<다른 트랜잭션, 락킹>

T2에서 update 실행 후 아예 없어지는게 아니라 대기가 되어 T1에서 commit을 하면 락킹이 풀려 T2에서 정상 실행 된다.

 

JDBC에서 트랜잭션 처리

JDBC에서 기본은 auto commit임

 

수동으로 하는법

con.setAutoCommit(false)

...

...

con.commit();

con.rollback();

 

SavePoint 검사점

con.setAutoCommit(false);
stmt.executeUpdate("Update 고객 set 적립금 =50 where 고객이름='정소화' ");

//sq1위로 commit이 된다.
Savepoint sp1 = con.setSavePoint( );
stmt.executeUpdate("Update 고객 set 적립금 =10 where 고객이름='김선우' ");
...
con.rollback(sp1); // sq1위엔 이미 commit이 됨. sq1아래로 Rollback이 된다.
...
con.commit( );

 

 

병행 제어

병행 수행(concurrency)

여러 개의 트랜잭션을 동시에 수행하는 것을 의미

여러 트랜잭션들이 차례로 번갈아 수행됨. 인터리빙(interleaving) 방식

 

병행 제어(concurrency control) 또는 동시성 제어

병행 수행 시 같은 데이터에 접근하여 연산을 실행해도 문제가 발생하지 않고 정확한 수행 결과를 얻을 수 있도록 

트랜잭션의 수행순서을 제어하는 것을 의미

 

병행수행 방안 == 병행제어

Read/Read는 단순히 읽는거기 때문에 상관x

Write/Write는 절때 허용하면 안됨=>2 page locking 작동

Read/Write는 3가지의 현상이 있다는 것이지, 잘못된것이 아님 => 이런것을 허용/불가 할껀지 고립수준 설정

 

병행수행 문제점(T1:W+T2:W)

1. 갱신 분실(lost update)

- 트랜잭션 변경 연산의 결과를 다른 트랜잭션이 덮어써 변경 연산이 무효화되는 것

- 여러 트랜잭션이 동시에 수행되더라도 트랜잭션들을 순차 수행한 것과 같은 결과 값을 얻을 수 있어야 함

 

2. 모순성(inconsistency) : 불일치 분석이라고도 함

- 일관성 없는 상태의 데이터를 가져와 연산함으로써 모순된 결과가 발생

- 여러 트랜잭션이 동시에 수행되더라도 모순성 문제가 발생하지 않고 마치 트랜잭션들을 순차적으로 수행한 것과 

  같은 결과 값을 얻을 수 있어야 함

 

 

3. 연쇄 복귀(cascading rollback)

- 트랜잭션이 완료되기 전 장애가 발생하여 rollback 연산을 수행하게 되면 장애 발생 전에 이 트랜잭션이 변경한 데이터

  를 가져가서 변경 연산을 실행한 다른 트랜잭션에도 rollback 연산을 연쇄적으로 실행해야 한다는 것

- 여러 트랜잭션이 동시에 수행되더라도 연쇄 복귀 문제가 발생하지 않고 마치 트랜 잭션들을 순차적으로 수행한 것

  과 같은 결과 값을 얻을 수 있어야 함

 

W+W 병행수행의 문제점 해결책 : 로킹(잠금)

트랜잭션 스케줄
- 트랜잭션에 포함되어 있는 연산들을 수행하는 순서

 

직렬 스케줄

각 트랜잭션별로 연산들을 순차적으로 실행시키는 것

병행수행안되서 속도가 느림


비직렬 스케줄

인터리빙 방식을 이용하여 트랜잭션들을 병행해서 수행시키는 것

병행수행은 되지만 여러가지 문제가생김


직렬 가능 스케줄

직렬 스케줄과 같이 정확한 결과를 생성하는 비직렬 스케줄

가능한 병행수행, 문제의 소지가 있으면 대기(락킹)을 이용함

직렬+비직렬의 단점을 보완한 스케줄 기법

 

해결책 : 트랜잭션 스케줄을 DBMS가 하도록 유도
직렬가능 스케줄 --> 락킹 기법 도입

 

 

락킹(Locking)

한 트랜잭션이 먼저 접근한 데이터에 대한 연산을 끝낼 때까지는 다른 트랜잭션이 그 데이터에 접근하지 못하도록

상호 배제(mutual exclusion)함

 

<기본 로킹 규약>

- 트랜잭션은 데이터에 접근하기 위해 먼저 lock 연산을 실행해 독점권을 획득함

- 다른 트랜잭션은 이미 lock 연산이 실행된 데이터에 대해 다시 lock 연산을 실행시킬 수 없음

- 독점권을 획득한 데이터에 대한 모든 연산의 수행이 끝나면 트랜잭션은 unlock 연산을 실행해서 독점권을 반납함

 

<효율성 향상>

트랜잭션들이 같은 데이터에 대해 동시에 read 연산을 실행하는 것을 허용(Read/Read)

 

공유(shared) lock

- 해당 데이터에 read 연산을 실행할 수 있지만 write 연산은 실행 할 수 없음. 
- 해당 데이터에 다른 트랜잭션도 공용 lock 연산을 동시에 실행 할 수 있음.
  (데이터에 대한 사용권을 여러 트랜잭션이 함께 가질 수 있음)

 

전용(exclusive) lock

- 해당 데이터에 read 연산과 write 연산을 모두 실행 할 수 있음. 
- 해당 데이터에 다른 트랜잭션은 공용이든 전용이든 어떤 lock도 불가능
  (전용 lock을 실행한 트랜잭션만 해당 데이터에 대해 독점권 가짐)

 

- MS-SQL : Select에 공유락을 거는 방식. wait 발생가능.
- Oracle : Select에 커밋된 것만 가져옴. 락을 걸지 않음

 

기본 로킹 규약으로 직렬 가능성이 보장되지 않는 스케줄 예

운영체제에 의해 다양한 스케줄이 존재할 수 있음

트랜잭션 T1이 데이터 X에 너무 빨리 unlock 연산을 실행하여 다양한 스케줄이 존재할 수 있음
해결책: 2단계 로킹 규약

 

2PL(2 phase Locking)

직렬 가능스케줄을 보장하는 가장 잘 알려진 규약

트랜잭션이 lock과 unlock 연산을 확장 단계와 축소 단계로 나누어 수행

 

확장단계 : 트랜잭션이 lock 연산만 실행할 수 있고, unlock 연산은 실행할 수 없는 단계

축소단계 : 트랜잭션이 unlock 연산만 실행할 수 있고, lock 연산은 실행할 수 없는 단계

트랜잭션은 첫 번째 unlock 연산 실행 전에 필요한 모든 lock 연산을 실행해야 함
=> 한 트랜잭션내에서 모든 lock 연산이 unlock 연산보다 앞선다

 

병행성을 최대화하면서 직렬 가능한 스케줄을 보장하는 방법이 있을까?
- 없다
- 2PL은 어느정도의 병행성은 제공

 

교착상태(deadlock)

- 트랜잭션들이 상대가 독점하고 있는 데이터에 unlock 연산이 실행되기를 서로 기다리면서 트랜잭션의 수행을 

  중단하고 있는 상태

- 처음부터 교착 상태가 발생하지 않도록 예방하거나, 발생 시 빨리 탐지하여 필요한 조치를 취해야 함

2PL이 교착상태를 해결하지는 못함

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Backend > Database' 카테고리의 다른 글

데이터베이스의 목적  (0) 2022.04.15
데이터베이스에 대해  (0) 2022.04.15
MariaDB 외부IP 접근 허용  (0) 2020.12.01
프로그램 GUI 구성 및 프로그램 기능들 정리  (0) 2020.11.10
7장. 트리거  (0) 2020.10.27
    'Backend/Database' 카테고리의 다른 글
    • 데이터베이스의 목적
    • 데이터베이스에 대해
    • MariaDB 외부IP 접근 허용
    • 프로그램 GUI 구성 및 프로그램 기능들 정리
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바