728x90
반응형
트랜잭션
개념
- 단일한 논리적인 작업의 단위(a single logical unit of work)
- 논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 업섹 만든 것
- DB에서 데이터를 다룰 때 장애가 일어난 경우, 데이터를 복구하는 작업의 단위가 됨
- DB에서 여러 작업이 동시에 같은 데이터를 다룰 때, 이 작업을 서로 분리하는 단위가 됨
- 트랜잭션은 전체가 수행되거나 전혀 수행되지 않아야 한다(
All or Nothing
)
START TRANSACTION;
UPDATE account SET balance = balance - 200000 WHERE id = 'J';
UPDATE account SET balance = balance + 200000 WHERE id = 'H';
COMMIT; -- ROLLBACK;
Autocommit
- 각각의 SQL문을 자동으로 transaction 처리해주는 개념
- SQL 문을 성공적으로 실행하면 자동으로 commit 한다
- 실행 중에 문제가 있었다면 알아서 rollback한다
- MySQL에서는 default로 autocommit이 enabled되어 있다
- 다른 DBMS에서도 대부분 같은 기능을 제공한다.
SELECT @AUTOCMMIT; -- 현재 AUTOCOMMIT 활성화 여부 확인, 1이면 활성화 0이면 비활성화
SET autocommit = 0;
DELETE FROM account WHERE balance <= 1000000;
SELECT * FROM account; -- 삭제된 모습이 보이지만 아직 transaction이 종료되지 않았기에, 롤백한다면 이전 상태로 돌아감.
- MySQL에서는
START TRANSACTION
실행과 동시에 autocommit은 off된다. - COMMIT / ROLLBACK과 함께 transaction이 종료되면 원래 autocommit 상태로 돌아간다.
ACID
Atomicity(원자성)
- ALL or NOTHING
- transaction은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 내부의 SQL문들이 모두 성공해야 한다
- 중간에 SQL문이 실패하면 지금까지의 작업을 모두 취소하여 아무 일도 없었던 것처럼 rollback한다.
Consistency(일관성)
- 트랜잭션을 수행하기 전이나 후나 데이터베이스는 항상 일관된 상태를 유지해야 한다
- transaction은 DB 상태를 consistent 상태에서 또 다른 consistent 상태로 바꿔줘야 한다
- constraints, trigger 등을 통해 DB에 정의한 rules을 transaction이 위반했다면 rollback해야 한다.
- transaction이 DB에 정의된 rule을 위반했는지는 DBMS가 commit 전에 확인하고 알려준다.
- 그 외에 application 관점에서 transaction이 consistent하게 동작하는지는 개발자가 챙겨야 한다.
- DB에 정의되지 않은 애플리케이션 관점의 일관성은 개발자가 챙기라는 것
Isolation(고립성)
- 수행 중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경 중인 데이터 값을 훼손하지 않아야 한다
- DBMS는 여러 종류의 isolation level을 제공하며, 개발자는 어떤 level로 transaction을 동작시킬지 설정할 수 있다.
- Concurrency Control(동시성 제어)의 주된 목표가 Isolation이다
Durability(지속성)
- 수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장한다
- commit된 transaction은 DB에 영구적으로 저장(= 비휘발성 메모리에 저장)한다.
- 즉, DB System에 문제가 생겨도 commit된 transcation은 DB에 남아있다
- commite된 경우 주기억장치 버퍼의 내용을 하드디스크에 확실히 기록해야 하며, 부분 완료(Partial Commit)된 경우에는 작업을 취소(Aborted)해야 한다. 즉, 정상적으로 완료 혹은 부분완료된 데이터는 DBMS가 책임지고 데이터베이스에 기록한다.
단, "DBMS 별로 트랜잭션 구현의 내용은 서로 다르다"
트랜잭션 상태
- Active: 트랜잭션이 시작되었거나 실행 중인 상태
- Partially Committed: 마지막 명령문을 실행시킨 직후의 상태로, 실패 또는 완료의 상태로 전이하게 됨
- Failed: 실행 중에 장애나 오류가 발생하여 정상적인 실행을 더 이상 할 수 없는 상태이며, 철회 상태로 전이하게 됨
- Aborted: Rollback 연산을 수행한 상태
- Committed: 수행 완료 상태
동시성 제어(Concurrency Control)
트랜잭션 스케줄(Transaction Schedule)
- 여러 트랜잭션들이 동시에 실행될 때, 각 트랜잭션에 속한 작업들의 실행 순서를 의미함
- 한 스케줄 내의 2개 이상의 트랜잭션이 있고, 각 트랜잭션은 여러 작업을 수행한다.
- 각 트랜잭션 내의 작업 순서는 바뀌지 않는다. 트랜잭션끼리의 순서만 바뀌지 한 트랜잭션 내의 순서는 바뀌지 않는다.
- 종류
- 직렬 스케줄(Serial Schedule)
- 트랜잭션의 연산을 겹치지 않고 한번에 하나씩 모두 순차적으로 실행하는 유형
- 한 번에 하나의 트랜잭션만 실행되기 때문에 동시성 문제가 발생하지 않음
- 하지만, 좋은 성능을 낼 수 없고, 현실적으로는 사용할 수 없는 방식임
- 비직렬 스케줄(Non-serial Schedule)
- 트랜잭션들이 직렬 수행 순서와 상관없이 겹쳐서 병행 수행하는 스케줄
- 트랜잭션들이 겹쳐서 실행되기 때문에 동시성이 높아져서 같은 시간 동안 더 많은 트랜잭션들을 처리할 수 있음
- 하지만, 트랜잭션들이 어떤 형태로 실행되는지에 따라 서로 영향을 주어 이상한 결과가 나올 수 있음..
- 직렬 가능 스케줄(Serializable Shedule)
- 스케줄이 직렬 실행은 아니지만, 직렬 스케줄과 동등한 결과를 내는 비직렬 스케줄을 의미 -> 결과가 equivalent함
- 서로 영향을 주지 않는 직렬 스케줄을 비직렬적으로 수행한다는 의미
- 두 개의 트랜잭션이 Read 연산만을 수행한다면, 상호 간섭이 발생되지 않으며 연산의 순서도 중요하지 않음
- 두 개의 트랜잭션이 같은 데이터 항목에 접근하지 않는다면, 상호 간섭이 발생되지 않으며 연산의 순서도 중요하지 않음
- 서로 다른 트랜잭션이 같은 데이터에 대해 각각 읽기와 쓰기를 한다면 실행 순서가 중요함
- 비직렬 스케줄이지만, 다른 직렬 스케줄과
confilc equilvalent
할 경우,conflict serializable schedule
이라고 한다.- 다음 두 조건을 모두 만족하면
confilc equilvalent
이다.- 두 스케줄은 같은 트랜잭션을 가진다
- 어떤 conflicting operations의 순서도 양쪽 스케줄 모두 동일하다.
- 다음 두 조건을 모두 만족하면
- 직렬 스케줄(Serial Schedule)
- 어떤 스케줄도 직렬 가능하게 만드는 역할을 수행하는 것이 Concurrency Control(동시성 제어)이다.
- 그리고 이것과 밀접하게 관련된 속성이 ACID 중 Isolation이다.
- 하지만, Isolation을 너무 추가하면 성능이 저하될 수 있기에 조금 relaxed하게 제공하는 방법이
Isolation Level
이다.
=> conflict serializable한 nonserial schedule을 허용하자!
회복 가능 스케줄(Recoveralbe Schedule)
Unrecoverable Schedule
- 스케줄 내에서 커밋된 트랜잭션 t1이 롤백된 트랜잭션 t2가 write 했었던 데이터를 읽은 경우, 이는 회복 불가능 스케줄이다.
- t1과 t2가 동시에 실행되어서 t2가 write 했던 값을 t1이 읽었다고 하자.
- 이때, 어떠한 문제로 t2를 rollback 시키게 된다면 t1은 유효하지 않은 값을 읽어서 작업한 셈이므로 t1도 롤백해야 한다. 하지만, t1은 이미 커밋된 상태라 durability 속성으로 인해 롤백될 수 없다..
- 즉, t1은
Unrecoverable Schedule
이다.
- 롤백을 해도 이전 상태로 회복 불가능할 수 있기 때문에 이런 스케줄은 DBMS가 허용하면 안된다. DBMS는 회복 가능한 스케줄만 허용해야 한다.
- 스케줄 내에서 커밋된 트랜잭션 t1이 롤백된 트랜잭션 t2가 write 했었던 데이터를 읽은 경우, 이는 회복 불가능 스케줄이다.
Recoverable Schedule
- schedule 내에서 그 어떤 transaction도 자신이 읽은 데이터를 write한 transaction이 먼저 commit/rollback 전까지는 commit 하지 않는 경우
- rollback 할 때, 이전 상태로 온전히 돌아갈 수 있기 때문에 DBMS는 이런 schedule만 허용해야 한다.
- 하나의 transaction(t2)이 rollback을 하면 의존성이 있는 다른 transaction(t1)도 rollback 해야 한다. ⇒
cascading rollback
- 하지만, 여러 트랜잭션의 롤백이 연쇄적으로 일어나면 처리 비용이 너무 크다.. -> 데이터를 write한 트랜잭션이 커밋/롤백 한 뒤에 데이터를 읽는 스케줄만 허용하자!
Cascadeless Schedule(= Avoid Cacading Rollback)
- 스케줄 내에서 어떤 트랜잭션도 커밋되지 않은 트랜잭션들이 write한 데이터는 읽지 않은 경우
- 하지만, 읽는 작업 자체가 없음에도
Lost Update
현상이 생길 수 있음..
Strict Schedule
- 스케줄 내에서 어떤 트랜잭션도 커밋되지 않은 트랜잭션들이 write한 데이터는 쓰지도 읽지도 않은 경우
- 롤백할 때 recovery가 쉽다! -> 트랜잭션 이전 상태로 돌려놓기만 하면 된다
최종 정리
- Unrecoverable Schedule은 롤백 발생 시 회복 불가능할 수도 있기 때문에 DBMS에서 허용해서는 안된다
- 하지만, Recoverable Schedule은 롤백 발생 시 회복 가능하기 때문에 허용해도 된다
- Recoverable Schedule = 어떤 트랜잭션이 write한 데이터를 또 다른 트랜잭션이 read했다면, write한 트랜잭션이 먼저 커밋/롤백 전까지는 read한 트랜잭션도 커밋하지 않는 경우
- Recoverable Schedule 중에서도, Cascading Rollback이 발생하지 않도록 하는 schedule =
Cascadeless Schedule
- Cascadeless Schedule 중에서도 더 엄격하게 커밋되지 않은 트랜잭션들이 write한 데이터는 쓰지도 읽지도 못하는 경우 =
Strict Schedule
=> Concurrency Control
은 serializability
와 recoverability
를 제공한다.
=> 이와 관련된 트랜잭션의 속성이 Isolation
이다.
728x90
반응형
'Database' 카테고리의 다른 글
[Database] Lock과 동시성 제어, 2PL (0) | 2024.10.06 |
---|---|
[Database] Transaction Isolation Level (0) | 2024.10.06 |
[Database] 테이블 설계 / FD / DB 정규화(Normalization) (4) | 2024.10.05 |
[Database] SQL Trigger (0) | 2024.10.05 |
[Database] Stored Function & Stored Procedure (2) | 2024.10.05 |