티스토리 뷰

반응형

http://www.kocw.net/home/cview.do?cid=d549f8570583094b 

https://techblog.wclub.co.kr/posts/0008.why-not-use-serializable-in-mysql/Mysql%EC%97%90%EC%84%9C%20SERIALIZABLE%EC%9D%84%20%EC%9E%98%20%EC%95%88%20%EC%93%B0%EB%8A%94%20%EC%9D%B4%EC%9C%A0

https://www.youtube.com/watch?v=aX9c7z9l_u8&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9CTech

https://www.youtube.com/watch?v=e9PC0sroCzc&t=514s&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9CTech

트랜잭션과 Rollback(Recovery)

트랜잭션은 같이 처리 되어야만 하는 것들을 원자적으로 연산할 수 있음을 지원해주는 것이다.

* 만약 계좌간 송금을 수행할 때, 송금자의 금액은 차감하였는데 수금자의 금액을 업데이트 하지 못 한 상태에서 DBMS가 HW,SW 적으로 멈추었다면?
* 만약 10,000 명의 직원들의 급여를 갱신할 때 도중 DBMS가 멈추었다면?

DBMS가 재가동 된 이후 어떻게 이전 가동 부터 다시 수행할 수 있을까? 디스크에 현재까지의 log를 기록하는 방법이다. 트랜잭션은 이러한 상황에서 회복하기 위해 Redo, Undo 로그를 기록한다. 이를 통해 원자성을 만족한다. 자세한 메커니즘은 off-topic이다. 이러한 recovery를 수행하는 이유는 ACID 성질을 만족하기 위함이고, commit과 Rollback(Recovery)를 수행한다

트랜잭션의 성질 ACID

A : Atomicity 원자성. 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야한다. 여러 명령 시 수행 중에 어느 하나라도 실패한다면 모두 없던일 로 되돌리는 Rollback을 수행한다. 또는 모두 성공적으로 수행되었다면 Commit을 통해 데이터베이스에 반영한다. Rollback 또는 Commit이 수행되어야 트랜잭션이 종료된다.
C : Consistency 일관성. 트랜잭션을 실행하기 전, 실행하고 나서 데이터베이스의 무결성을 반드시 지키고 있어야한다. 트랜잭션 중간에는 지키지 않아도 되지만, 트랜잭션이 끝난 후에는 데이터베이스가 지켜야할 규칙을 반드시 지켜야 하는 상태여야한다. 
I : Isolation 독립성. 둘 이상의 트랜잭션이 동시 실행되고 있을 때 서로 간섭없이 독립적으로 이루어져야한다. 두 쓰레드/프로세스가 공유된 자원을 두고 경쟁할 때 경쟁조건이 발생하는 것 처럼, 두 트랜잭션 또한 경쟁조건이 발생할 수 있다. 이러한 상황이 발생하면 안된다.
예로, 트랜잭션1 에서 A 계좌에서 B 계좌로 1원 송금하고, 트랜잭션 2에서 C 계좌에서 B 계좌로 1원 송금할 때 경쟁조건이 발생한다면, A, C 계좌에서 출금이 된 것에 반해 B 계좌는 1원 만 송금받은 상태로 된다. 
D: Duration 지속성. 트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야한다.

트랜잭션의 격리 수준, 정합성과 동시성은 반비례한다.

트랜잭션은 동시성을 제어하기 때문에, 속도가 매우 느릴 수 있다. 격리 수준을 조절하여 다양한 방법으로 문제를 해결할 수 있다. 격리 수준이 낮을 수록 동시에 실행되는 트랜잭션이 늘어나고, 격리 수준이 높을 수록 동시에 실행되는 트랜잭션이 줄어든다. 격리 수준이 가장 높은 Serializable에서는 모든 트랜잭션이 다른 트랜잭션이 끝났을 때 실행 되므로 가장 느리다. 각각의 격리 수준 중 무엇이 더 좋고, 무엇이 더 나쁘다 라고 할 수 없으며 각 각의 웹 서비스마다 그 도메인이 트랜잭션을 결정한다. 계좌 송금과 공항 좌석 예매의 트랜잭션이 똑같이 원자성을 지켜야한다고 하더라도 같은 격리 수준에서 개발한다고 보장할 수 없다. 

READ UNCOMITTED

* 트랜잭션이 실행되고 있더라도, 다른 트랜잭션이 해당 트랜잭션이 수행한 값을 읽어오는 것은 허용. 
* 실행되고 있는 트랜잭션이 commit, rollback 여부와 상관없이, 다른 트랜잭션은 본인 실행 시점에서의 릴레이션을 읽어온다.
* Dirty Read Problem이 발생할 수 있다. 다른 트랜잭션이 읽고 난후 실행하고 있던 트랜잭션이 rollback 한 경우. 또는 다른 트랜잭션이 읽고 난 후 실행하고 있던 트랜잭션이 값을 변경후 commit한 경우.
* 만약 n개의 트랜잭션이 연쇄적으로 dirty read 한 경우 어떻게 처리해야할까? 질문 글을 독자분께 남겨본다. (나도 잘 모름)

READ COMMITED

* 트랜잭션이 실행되고 있을 때, 다른 트랜잭션은 이전 내용을 가져온다. 이때 다른 트랜잭션은 이전 내용은 테이블을 참조 하지 않고, undo log를 활용한다.
* 실행되고 있는 트랜잭션이 commit을 수행 한 후, 다른 트랜잭션은 반영 이후 내용을 가져온다. 
* Non-Repeatable Read, Phantom Read 문제가 발생할 수 있다. Non-Repeatable은 같은 트랜잭션 내에서 조회만 두 번 하였는데 그 값이 다른 상황을 뜻한다.

REPEATABLE READ

* 트랜잭션내에서 조회하는 경우 해당 조회 결과가 항상 동일하다는 것을 보장한다. 

우측 Transaction2 에서는 동일한 Select 결과를 반환한다.


* Phantom Read 현상이 발생한다. 추가, 삭제 등의 작업이 다른 트랜잭션을 수행할 때 영향을 받아 aggregation function 등을 수행할 때 쿼리에서 잘못된 값을 읽게 된다.
* 다만, DBMS 각각 REPEATABLE READ 모드에 대해 추가적인 작업을 하기 때문에, phantom read 현상은 일어나지 않는다. mysql, postgresql 등의 DBMS는 각자의 알고리즘으로 Phantom Read를 해결하고 있다고 한다. 

Serializable

* 모든 트랜잭션은 독립적으로 실행된다. 한 트랜잭션이 실행되기 데이터베이스에 전까지 접근을 할 수 없다. 

의외로 트랜잭션은 DBMS의 성능을 측정하는데 사용된다. 사용자가 DBMS를 이용할 때, 그 DBMS 까지 가는데에 CPU ~> DISK (HW)~> OS (Kernel) ~> 응용프로그램, DBMS (SW) 의 단계가 있다. 이러한 단계 중에서 DBMS의 성능을 측정할 때 Transaction Per Second, TPS가 활용된다. (자세한 내용은 off-topic)

 

반응형

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

인덱스  (0) 2022.01.18
인강 1) 관계 대수와 SQL  (0) 2021.06.29