트랜잭션(Transaction)이란?
트랜잭션이란 하나의 작업을 수행하기 위해 필요한 데이터베이스 연산들을 모아놓은 것.
데이터베이스의 논리적인 작업 단위이며, 장애가 발생했을 때 데이터를 복구하는 작업의 단위이다.
트랜잭션은 데이터베이스가 항상 정확하고 일관된 상태를 유지할 수 있고, 오류 발생 시 빠르게 복구할 수 있도록 하는데 중요한 역할을 합니다.
트랜잭션은 데이터베이스 서버에 다수의 클라이언트가 동시에 액세스하거나 응용프로그램이 갱신을 처리하는 과정에서 중단될 수 있는 경우 등 데이터 부정합을 방지하고자 할 때 사용합니다.
하나의 프로세스로만 처리할 경우 부정합은 발생하지 않지만, 효율이 너무 떨어지기 때문에
병렬로 처리 시 부정합을 방지하고자 트랜잭션을 사용합니다.
DBMS의 성능은 초당 트랜잭션의 실행 수( TPS : Transaction per second )로 측정합니다.
트랜잭션의 특성 (ACID)
- Atomicity (원자성)
- Consistency (일관성)
- Isolation (격리성)
- Durability (지속성)
1. 원자성 (Atomicity)
'All or Nothing'
트랜잭션을 구성하는 연산들이 모두 정상적으로 실행되거나 하나도 실행되지 않아야 한다.
트랜잭션을 수행하다가 장애가 발생하여 작업을 완료하지 못했다면, 실행한 연산을 모두 취소하고 데이터베이스를 트랜잭션 작업 전의 상태로 되돌려 원자성을 보장.
(자금 이체의 예로, 이체 과정 중 예금이 사라지는 경우가 발생해서는 안됨)
트랜잭션의 원자성을 보장하려면 장애가 발생했을 때 데이터베이스를 원래 상태로 복귀하는 회복 기능이 필요.
▶ 원자성 보장
트랜잭션에서 원자성은 수행하고 있는 트랜젝션에 의해 변경된 내역을 유지하면서, 이전에 commit된 상태를 임시 영역에 따로 저장함으로써 보장합니다.
즉, 장애가 발생하면 현재 내역을 날려버리고 임시 영역에 저장했던 상태로 rollback
커밋된 상태가 저장되는 임시 영역이 롤백 세그먼트 (rollback segment)이며,
현재 수행하는 트랜잭션에 의해 변경되는 내역이 데이터베이스 테이블
트랜잭션의 길이가 길어진다면, 장애가 발생했을 시 이전에 오류가 발생하지 않은 작업도 반복하여 수행하여야 하므로,
오류가 발생하지 않은 확실한 부분에 대해서는 savepoint를 지정할 수 있습니다.
2. 일관성 (Consistency)
트랜잭션이 성공적으로 완료되면 일관적인 DB 상태를 유지하는 것
(계좌 이체의 예로, 진행 전의 돈의 합과 진행 후의 돈의 합이 같아야 함)
트랜잭션이 수행되기 전에 데이터베이스가 Correct State라면, 트랜잭션을 수행하고 난 후에도 Correct State여야 한다.
Correct State 란?
도메인의 유효범위, 무결성 제약조건 등의 제약조건을 위배하지 않는 정상적인 상태
▶ 일관성 보장
트랜잭션에서 일관성은 트랜잭션 수행 전, 후에 데이터 모델의 모든 제약 조건을(기본키, 외래키, 도메인 등)을 만족하는 것을 통해 보장.
위의 상황의 경우 Movie 테이블이 변경되면, Video 테이블에서도 movie_id가 변경되어야 함.
이때, 필요한 것이 트리거 (Trigger)
트리거는 특정 테이블에 insert, delete, update 같은 DML 문이 수행되었을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램.
1
2
3
4
5
6
7
8
|
CREATE OR REPLACE TRIGGER movieId_check
AFTER UPDATE OF movieId on Movie
for each row
DECLARE
---
BEGIN
---
END
|
cs |
1~5 LINE
트리거 선언
movie 테이블에 update가 발생하면 그 이후(after) each row에 대해 trigger를 적용한다라는 뜻.
declare 선언문에는 변수 선언
3. 격리성 (Isolation)
트랜잭션 수행 시 다른 트랜잭션의 작업이 끼어들지 못하도록 보장하는 것
즉, 트랜잭션끼리는 서로 간섭할 수 없다.
시스템에서 여러 트랜잭션이 동시에 수행되지만, 각 트랜잭션이 독립적으로 수행될 수 있도록 중간 결과에 대해 서로 접근하지 못하게 한다.
(계좌 이체의 예로, A->B에게 돈을 송금할 때 다른 트랜잭션이 끼어들어 B에게 돈을 보낼 수 없음. A->B 이후 보냄.)
Isolation 성질이 보장되지 않으면 트랜잭션이 원래 상태로 되돌아갈 수 없게된다.
Isolation 성질을 보장할 수 있는 가장 쉬운 방법은 모든 트랜잭션을 순차적으로 수행하는 것 => 효율 떨어짐
DBMS는 병렬적 수행의 장점을 얻기 위해 병렬적으로 수행하면서도 일렬(Serial) 수행과 같은 결과를 보장할 수 있는 방식 제공.
▶ 병행 처리 (Concurrent Processing)
CPU가 여러 프로세스를 처리하는 것처럼, 트랜잭션에 정해진 시간을 할당해서 작업을 하다가 부여된 시간이 끝나면 다른 트랜잭션을 실행하는 방식으로 트랜잭션들을 조금씩 처리하는 것.
이렇게 되면, 부분적으로 처리되는 과정에서 공통된 데이터를 조작하여 오류 발생 가능.
이와 같이 트랜잭션에 간섭이 일어날 경우 갱신 분실(lost update), 연쇄 복귀(cascading rollback) 또는 회복 불가능(Unrecoverability), 불일치 분석(inconsistent analysis) 등과 같은 문제가 발생할 수 있음.
≫ 갱신 분실(lost update) : 트랜잭션들이 동일한 데이터를 동시에 갱신하는 경우에 발생. 또는 이전 트랜잭션이 데이터를 갱신한 후 트랜잭션이 종료하기 전에 나중 트랜잭션이 동일한 데이터를 갱신하여 갱신 값을 덮어쓰는 경우에 발생하는 문제
≫ 연쇄 복귀(cascading rollback) or 회복 불가능(Unrecoverability) : 여러 개의 트랜잭션이 데이터를 공유할 때, 특정 트랜잭션이 이전 상태로 복귀(rollback)할 경우 아무 문제 없는 다른 트랜잭션까지 연달아 복귀하게 되는 문제. 이때 한 트랜잭션이 이미 완료된 상태라면 트랜잭션의 지속성 조건에 따라 복귀 불가능
▶ 고립성 보장
OS의 세마포어(semaphore)와 비슷한 개념으로 lock & excute unlock을 통해 고립성 보장 가능
데이터를 읽거나 쓸 때 lock을 걸어 다른 트랜잭션이 접근하지 못하도록 고립성을 보장하고, 수행을 마치면 unlock을 통해 데이터를 다른 트랜잭션이 접근할 수 있도록 허용하는 방식.
트랜잭션에서는 데이터를 읽을 때, 여러 트랜잭션이 접근할 수 있도록 허용하는 공유 잠금(shared_lock)을 한다.
shared_lock은 오직 데이터 읽기만을 허용함 (쓰기 허용 X)
데이터를 쓸 때는 다른 트랜잭션이 접근할 수 없도록 하는 배타 잠금(exclusive_lock)을 한다.
작업이 끝나면 unlock을 통해 잠금을 푼다.
lock과 unlock을 잘 못 사용하면 데드락(deadlock) 상태에 빠질 수 있음.
▶ 2PL 프로토콜 (2 Phase Locking protocol)
데드락 문제를 해결하기 위해 나온 프로토콜
여러 트랜잭션이 공유하고 있는 데이터에 동시에 접근할 수 없도록 하기 위한 목적을 가진 프로토콜.
2가지 단계의 Locking이 존재. ( Growing Phase와 Shrinking Phase )
확장 단계 (Growing phase)는 read_lock, write_lock을 의미, 축소 단계 (Shrinking phase)는 unlock을 의미.
2PL 프로토콜은 확장과 축소의 단계가 섞이면 안된다는 것을 의미한다.
확장 단계에는 lock만, 축소 단계에는 unlock만!
병행처리 시 트랜잭션의 고립성을 보장하기 위해서는 2PL 프로토콜을 사용해아함 → Serializable Schedule
하지만, 2PL 프로토콜을 사용하더라도 교착 상태 문제가 발생할 수 있다.
위 문제를 해결하는 가장 간단한 방법으로 각 트랙잭션을 시작하기 전에 모든 필요한 잠금을 동시에 설정하면 해결 가능.
혹은, 교착상태 회피 방법이나 탐지 방법을 사용.
4. 지속성 (Durability)
성공적으로 수행된 트랜잭션은 영원히 반영
즉, commit을 하면 상태가 영원히 보장.
시스템에 장애가 발생하더라도 트랜잭션이 성공적으로 완료되어 커밋 된 후라면 작업 결과는 없어지지 않고 데이터베이스에 그대로 남아있어야 함.
트랜잭션의 지속성을 보장하려면 시스템에 장애가 발생하였을 때 데이터베이스를 원래 상태로 복구하는 회복 기능이 필요.
트랜잭션의 상태
≫ 활동 상태
트랜잭션이 수행을 시작하여 현재 수행중인 상태
≫ 부분 완료 상태
마지막 연산이 실행된 직후의 상태
연산은 모두 처리한 상태이지만, 수행한 최종 결과를 데이터베이스에 반영하지 않은 상태
≫ 완료 상태
트랜잭션이 성공적으로 완료되어 commit 연산을 완료한 상태
≫ 실패 상태
장애가 발생하여 수행이 중단된 상태
≫ 철회 상태
수행이 실패하여 rollback 연산을 실행한 상태
댓글