반응형

트랜잭션(Transaction)

- 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다.(wikipedia)

쉽게 설명하면, '데이터베이스의 상태를 변화시키는 단위'이다.

데이터베이스의 상태를 변화시키는데 있어서, 다음과 같은 4가지 조건 ACID를 만족해야한다.

  • 원자성(Atomicity) : 하나의 트랜잭션 안의 연산들은 DB에 '모두' 반영되던지(commit), '모두' 반영되지 않아야 한다(rollback).
  • 일관성(Consistency) : 트랜잭션이 완료되면 DB는 일관된 상태를 유지해야 한다.
    • 일관된 상태란 DB의 무결성 제약조건, 고정된 데이터 타입, 유효 범위 등을 만족하는 상태
  • 독립성(Isolation) : 트랜잭션은 독립적으로 실행되야 한다. 즉 트랜잭션끼리 연산 중간에 서로 간섭하거나 열람할 수 없다.
  • 영속성(Durability) : 완료된 트랜잭션은 DB에 영원히 반영되어야 한다. 

 

 

 

트랜잭션을 왜 사용할까? 

→ 위에서 트랜잭션 실행의 조건을 보면 알 수 있듯, 데이터의 값이 일괄적으로 변하는 과정에서 데이터의 부정합을 '효과적으로' 방지할 수 있다는 점이 가장 큰 요인일 것이다.

(비록 스케줄링 비용, 속도 저하가 발생하지만 ACID가 보장되지 않을 때 발생할 수 있는 문제들을 생각하면...)

 

 

 

트랜잭션 조건 보장

  • 원자성 : 모든 트랜잭션은 실행되기 전에 원본을 'rollback segment'라는 저장 공간에 유지한다. 따라서 트랜잭션 도중에 오류가 발생하면 연산을 중지하고 저장되 있는 원본 상태로 rollback이 가능하며, 트랜잭션 연산을 다시 수행한다.
    • save point : 트랜잭션이 길어짐에 따라 연산 도중 오류 발생시 '원본으로 rollback → 재실행' 비용이 커지게 된다. 이 때, 확실하게 완료된 연산 지점에 save point를 두고 '원본'이 아니라 'save point'로 rollback하여 트랜잭션 재실행 시간을 절약할 수 있다. 
  • 일관성 : 트리거(Trigger)를 통해 보장한다.
    • 트리거 : DB의 데이터를 DML 연산 중, 추가(INSERT), 삭제(DELETE), 수정(UPDATE) 했을 때, DB 자체적으로 자동으로 실행하는 작업이다. 트랜잭션 연산에 일관성을 위배시키는 작업이 있더라도, 이를 방지하기 위한 트리거를 적용해 놓음으로써 문제가 되지 않는다.
  • 독립성 : 여러개의 트랜잭션이 실행되면 프로세스가 빠르게 번갈아가며 CPU를 사용하는 multi-programming 처럼 병행 처리된다. 즉, 트랜잭션1이 실행되다가 트랜잭션2가 실행될 수 있다. → 그렇기 때문에 독립성을 고려해야함 
    • 멀티 프로세싱, 멀티 스레딩의 경우 단일 공유자원에 두 개 이상이 접근하면 문제가 발생하는데, 이를 방지하기 위해 뮤텍스를 사용하듯, 트랜잭션끼리 얽히지 않기 위해 lock & unlock 기법을 사용한다.
      • lock은 대표적으로 shared lock과 exclusive lock이 있다.
      • shared lock : A 트랜잭션이 자원을 read 할 때의 locking, 데이터가 변경되지 않을 것이기 때문에 다른 B 트랜잭션이 동시에 read할 수 있다.(이 때, B 트랜잭션도 shared lock을 건다.) 하지만, 그 어떤 트랜잭션도 shared lock이 걸린 자원에 write 할 수 없다.
      • exclusive lock : A 트랜잭션이 자원에 write 할 때의 locking, 데이터가 변경될 것이기 때문에 그 어떤 트랜잭션도 read, write 모두 할 수 없다.
      • ex. 여러 트랜잭션이 하나의 자원에 shared lock을 '동시에' 걸 수 있다. 하지만 이 모든 shared lock이 unlock 되기 전까지는 해당 자원에 exclusive lock을 걸 수 없다.
    • lock & unlock 기법을 잘못 사용하면 deadlock과 같은 교착 상태가 발생한다. 따라서 lock & unlock도 규칙을 가지고 실행하게 된다(ex. 2PL protocol). 하지만 규칙의 'strict한 정도'와 '처리의 병행성'은 Trade-off 관계로, 엄격한 규칙을 적용하면 교착 상태를 보다 더 예방할 수 있지만 병행 처리가 늦어지고, 반대의 경우는 병행 처리 속도는 증가하지만 문제 발생 확률이 증가한다. 

 

 

2PL protocol(2 Phase Locking Protocol)

2PL 프로토콜은 트랜잭션의 병행 처리시, 독립성을 보장하기 위한 lock - unlock 과정에서 생기는 deadlock을 예방하기 위한 방법 중에 하나이다. (완전한 예방은 아니다. 가능성을 줄여줄 뿐..)

- 트랜잭션이 여러 자원을 사용할 때, lock만 하는 단계(growing phase) and unlock만 하는 단계(shrinking phase)로 나눠지게끔 한다.

 ex. growing→ read_lock(x), write_lock(y), read_lock(z), ...  | shrinking→ unlock(z), unlock(x), unlock(y), ... 

 

(만약 자원이 필요할 때 lock, 쓰고 unlock, 다시 필요하면 lock,...을 반복하면 당연히 deadlock은 확률이 증가할 것이다.

또한, 사용할 자원들을 모두 lock할 때까지 기다리고, 일괄적으로 연산한 뒤에 한번에 unlock해야 하는게 아니다. 

필요한 자원을 lock 하면서 연산하고 더 이상 lock할 자원이 없을 때부터 필요 없어진 자원이 생기면 순차적으로 unlock하는 것이다.)

 

 

트랜잭션의 상태

  • Active : 트랜잭션 실행중
  • Failed : 트랜잭션 실패 → 연산 중단
  • Aborted : rollback 완료
  • Partially committed : 마지막 연산 완료, commit 대기 (하드웨어, 시스템적 문제로 장애가 발생할 수 있다고 한다.)
  • Committed : 트랜잭션 완료, 종료 → commit 실행

 

 

 

 

 

 

출처

coding-factory.tistory.com/226

victorydntmd.tistory.com/129

mommoo.tistory.com/62

coding-factory.tistory.com/226

medium.com/pocs/%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4-%EA%B8%B0%EB%B2%95-%EC%9E%A0%EA%B8%88-locking-%EA%B8%B0%EB%B2%95-319bd0e6a68a

(strict 2pl 부분 추가 예정)

반응형

'IT study > Notebooks' 카테고리의 다른 글

OS - paging and Segmentation  (0) 2021.04.30
OS - Global Interpreter Lock(feat. python)  (0) 2021.04.21
OS - Deadlock  (0) 2021.04.11
OS - Cache(feat. Page 교체)  (0) 2021.04.08
OS - 세마포어(Semaphore), 뮤텍스(Mutex)  (0) 2021.04.06

+ Recent posts