Trasaction
- Trasaction은 데이터베이스의 단일한 논리 작업 단위를 의미함
논리적인 이유로 여러 SQL문을 하나로 나누어 나뉠 수 없게 한 것
- Transaction의 SQL문 중에 일부만 성공해 DB에 반영될 수는 없음
START TRANSACTION;
UPDATE account SET balance = balance - 200000 WHERE id = 'J';
UPDATE account SET balance = balance + 200000 WHERE id = 'H';
COMMIT;
- DB가 자동으로 commit, rollback 처리를 하게 해두려면 ATUOCOMMIT을 사용
SET autocommit = 0;
SET autocommit = 1;
ACID
- Transaction에서 Atomicity, Consistency, Isolation, Durability를 합쳐 ACID라 부름
Atomicity
- transcaction은 논리적으로 쪼갤 수 없는 작업 단위이기 때문에 내부의 SQL문들이 모두 성공하거나 모두 실패해야 함을 의미
- 중간의 SQL문이 실패하면 지금까지의 작업을 모두 취소해 아무 일도 없던 것처럼 롤백해야 함
- 개발자는 commit, rollback 타이밍을 잘 챙겨주어야 함
Consistency
- Transaction은 DB의 상태를 consistent 상태에서 다른 consistent 상태로 바꿔줘야 함을 의미
- constraints, trigger등을 통해 정의한 DB의 규칙을 위반하면 Transaction을 중단하고 롤백해야 함
- Transaction이 규칙을 위반했는지는 DBMS가 commit 전에 확인하고 알려줌
Isolation
- 여러 Transaction이 동시에 실행될 때도 혼자 실행되는 것처럼 동작하게 만드는 것을 의미
- DBMS는 여러 종류의 isolation level을 제공하며, 개발자가 이를 선택할 수 있음
- Concurrency control의 주된 목표는 isolation이 됨
Durability
- commit된 transaction은 DB에 영구적으로 저장됨을 의미
- DB 시스템에 문제가 생겨도 commit Transaction은 DB의 비휘발성 메모리에 남아 있게 됨
- DBMS의 durability는 DBMS가 보장함
Concurrency control
Schedule
- 여러 transaction들이 동시에 실행될 때 각 transaction에 속한 operation들의 실행 순서를 Schedule이라 함
- 각 transaction내에 operation들의 순서는 바뀌지 않음
- 각 스케줄이 겹치지 않고 순차적으로 실행되는 스케줄을 Serial schedule이라 함
- 트랜젝션이 겹쳐 순차적으로 실행되지 않는 스케줄을 Nonserial schedule이 됨
- Serial schedule은 DBMS성능을 감소시키기 때문에 데이터베이스에서는 Nonserial schedule을 사용함
- Nonserial schedule 스케쥴끼리의 충돌이 발생해 예상치 못한 결과가 일어날 수 있으며, 실제 사용을 위해서는 Serial schedule과 동등한 결과를 보장해줄 필요가 있음
conflicit
- 두 연산이 아래의 세가지 조건을 만족하면 conflict가 일어난다 함
- 서로 다른 transaction 소속이고
- 같은 데이터에 접근하며
- 적어도 하나는 write opertaion이어야 함
- conflict operation은 순서가 바뀔시 결과도 바뀌게 됨
- 두 스케줄이 아래의 두가지 조건을 만족하면 conflict equivalent라 함
- 두 스케줄이 같은 transaction을 가지며
- 어떤 conflicting operation의 순서도 양쪽의 스케줄이 동일해야 함
r1(K) w1(K) r2(H) w2(H) c2 r1(H) w1(H) c1
r2(H) w2(H) c2 r1(K) w1(K) r1(H) w1(H) c1
둘은 순서는 다르지만 같은 transaction을 처리하며, 연산이 conflict되는 데이터간의 순서가 동일하기 때문에 (r2(H) -> r1(H), w2(H) -> w1(H)) conflict equivalent조건이 됨
- Serial schedule과 conflict equivalent한 Nonserial schedule을 conflict serializable이라 하며, Serial schedule과 동일한 결과를 냄
- DB를 구축할때는 conflict serializable이 아니면서 conflict가 일어나는 스케줄이 처리되지 않도록 해야 함
recoverability
- 데이터베이스의 데이터를 롤백했을 때, 다른 트랜잭션도 롤백될 수 있는지 여부를 recoverability라 함
가령 r1(K) w1(k) r2(H) w2(H) r1(H) w1(H)에서 두번째 트랜젝션을 먼저 롤백했을 경우 첫번째 트랜젝션은 롤백을 해야함에도 불구하고 Durability 문제로 인해 롤백할 수 없게 됨
- rollback을 해도 이전 상태로 회복 불가능한 스케줄은 unrecoverable schedule이라 함
unrecoverable schedule을 DBMS에서 허용해서는 안되며, recoverable schedule이 되도록 커밋 순서를 조정해야 함
- recoverable schedule에서 의존성을 가지는 트랜젝션을 동시에 롤백하는 것을 cascading rollback이라 함
- cascading rollback은 퍼포먼스를 많이 소모하기 떄문에 commit이 된 다음에 의존하는 데이터를 읽는 방식을 통해 성능을 향상시킬 수 있는데, 이러한 방식은 cascadeless schedule이라 부름
- cascadeless schedule에서 롤백을 시도시에 중간 결과가 사라질 수 있는데, 이를 방지하기 위해서 의존되는 transaction의 커밋이 완료되기 전까지 읽지도 쓰지도 않는 방식을 strict schedule이라 함
isolation
- 트랜젝션시에 rollback으로 인해 아래와 같은 문제가 발생할 수 있음
- 롤백으로인해 현재의 데이터가 커밋이 되지 않은 상태가 되고, 그 값을 읽는 경우 (dirty read)
- 같은 데이터를 읽는 동안에 다른 트랜젝션으로 인해 값이 바뀌고, 한 트랜젝션에서 같은 데이터 값이 달라지는 경우 (non-repeatable read)
- 같은 데이터를 읽는 동안에 다른 트랜젝션으로 인해 값이 추가되어, 한 트랜젝션에서 같은 데이터 값이 달라지는 경우 (phantom read)
- SQL 표준에서는 위의 문제를 허용하는지 여부에 따라 isolation의 단계를 구분함
- Read umcommited는 dirty read, non-repeatable read, phantom read 모두를 허용함
- Read commited는 dirty read를 비허용하고 non-repeatable read, phantom read 를 허용함
- Repeatable read는 dirty read, non-repeatable read를 비허용하고, phantom read를 허용함
- Serializable는 dirty read, non-repeatable read, phantom read 모두를 허용하지 않음
- SQL 표준에서 정의되지 않는 이상 현상들은 아래와 같음
- 커밋이 되지 않은값을 바탕으로 값을 write하는 경우 (dirty write)
- 값의 업데이트가 중복되어 한 트랜젝션의 업데이트가 무시당하는 경우 (lost update)
- 롤백이 되지 않음에도 불구하고 write가 있을 경우 dirty read가 발생할 수 있음
- 트랜젝션으로 인해 도중에 값이 바뀌어 원본 데이터와 트랜젝션 데이터의 정합성이 일치하지 않는 경우 (read skew)
- 트랜젝션으로 인해 도중에 값이 바뀌어 트랜젝션 시 데이터의 정합성이 깨지는 경우
- phantom read의 경우 연관되는 데이터의 불일치가 발생하는 경우로 확장할 수 있음
- 이 문제를 해결하기 위해 스냅샷을 사용해 isolation을 관리하는 방법을 snapshot isolation이라 함
- 트랜잭션 시작시점에 스냅샷을 기반으로 데이터를 수정하고, 데이터의 정합성에 문제가 없을때에만 커밋을 허용하는 방법
MVCC
- Lock을 사용해 값의 변화를 방지하려 하는 경우에는 읽기, 쓰기의 불필요한 차단으로 인해 성능에 나쁜 영향을 주는 문제가 발생함
- 문제를 해결하기 위해서는 write lock, read lock끼리의 상호 간섭을 없에야 하며, 이러한 concurrency control 기법을 MVCC (multivision concurrency control) 이라 함
- MVCC를 사용할때는 특정한 시점을 기준으로 가장 최근에 커밋된 값을 읽어오게 되며, 이를 위해 데이터 변화 이력을 관리함
- MVCC가 동작하는 방법은 isolation 레벨에 따라 바뀌게 됨
LOCK
- 데이터의 읽기, 쓰기가 발생했을 때 읽기, 쓰기 제한을 걸어 값의 예상치 못한 변화를 방지하는 방법
- 읽기는 허용하고 쓰기만을 방지하는 read-lock, 읽기, 쓰기를 모두 막는 write lock이 있음
- 트랜잭션에서 lock이 중첩되어 정상적인 값 수정이 이루어지지 않을 경우 Nonserializable 현상이 발생할 수 있음
- 트랜젝션의 serializable을 유지하기 위해서는 한 트랜젝션에서 모든 lock 연산이 unlock 연산보다 우선 수행되야 하며, 이러한 트랜젝션을 two-phase locking이라 함
- Nonserializable을 방지할 수 있지만, lock 해제를 무한히 기다리는 데드락이 발생할 수 있음
- lock을 취득하는 방법에 따라 2PL을 구분할 수 있음
- conservative 2PL은 모든 lock을 취득한 다음에 transaction을 시작함
- strict 2PL은 strict schedule을 보장할 수 있도록 해주는 two-phase locking을 의미하며, write-lock은 커밋 또는 롤백시에 반환됨
- strong strict 2PL은 strict 2PL과 동일하지만, read-lock 역시 커밋 또는 롤백시에 반환된다는 차이가 있음
출처:
https://www.youtube.com/watch?v=sLJ8ypeHGlM&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=14
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=15
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=16
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=17
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=18
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=19
https://www.youtube.com/watch?v=DwRN24nWbEc&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=20
유익한 글 잘 봤습니다, 감사합니다.