Transaction Flashcards
트랜잭션(Transaction)
데이터베이스의 상태를 변환시키는 하나의 논리적인 작업 단위를 구성하는 연산들의 집합이다.
Commit 연산
한개의 논리적 단위(트랜잭션)에 대한 작업이 성공적으로 끝나 데이터베이스가 다시 일관된 상태에 있을 때, 이 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산이다.
Rollback
하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때, 이 트랜잭션의 일부가 정상적으로 처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산이다. Rollback 시에는 해당 트랜잭션을 재시작하거나 폐기한다.
트랜잭션의 성질(ACID)
원자성(Atomicity) 일관성(Consistency)
격리성(Isolation) 지속성(Durability)
트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질이다.
동시성제어와 회복 기법을 활용하여 보장한다.
원자성 보장
원자성은 트랜잭션이 반드시 완수되어야 함을 의미한다. 만일 원자성을 따르지 않는다면 트랜잭션은 붕괴된다.
원자성은 데이터 무결성을 망가뜨리는 부분적으로 완료된 트랜잭션으로 절대로 남아있지 않도록 보장한다.
은행에서 돈을 인출한다고 가정하자 인출을 완료하였지만 두 번째 요청이 실패하여 해당 시스템은 또 다른 은행에서 돈을 꺼내올 수 없는 경우 두 요청 모두 실패해야 한다.
동시성 (Consistency)
transaction이 끝날 때 DB의 여러 제약 조건에 맞는 상태를 보장하는 성질이다. 송금하는 사람의 계좌 잔고가 0보다 작아지면 안 된다.
고립성
트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다.
지속성(Durability)
성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다.
시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다.
전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.
동시성 제어
다양한 Lock 기법을 이용해 동시성 제어
Locking 기법(2단계 로킹) : Shared Lock, Exclusive Lock을 활용한 제어
TimeStamp 기법 : 트랜잭션의 시작 시간을 이용해 제어 낙관적(검증) 기법 : 각 트랜잭션마다 Copy해서 작업 후 변동 부분을 검증하며 한꺼번에 반영
Locking, TimeStamp등을 활용한 다중버전(MVCC) 기법(유명한 DBMS에서 많이 사용👍) : 한 데이터 항목에 대해 여러개의 버전을 이용하여 이전 버전의 데이터를 활용한 처리방법
회복 기법
트랜잭션 고장, 시스템 고장, 매체 고장 등으로 문제가 생겼을때 회복하는 방법
트랜잭션 고장 : Rollback을 통한 undo
시스템 고장 : WAL 기법을 통한 undo, redo
매체 고장 : 백업
Transcation의 상태 변화를 그림으로 나타내시오
Active
Failed
Partially Committed
Committed
Aborted
Partially Committed 와 Committed 의 차이점
Active
트랜잭션의 활동 상태. 트랜잭션이 실행중이며 동작중인 상태를 말한다.
Failed
트랜잭션 실패 상태. 트랜잭션이 더이상 정상적으로 진행 할 수 없는 상태를 말한다.
Partially Committed
트랜잭션의 Commit 명령이 도착한 상태. 트랜잭션의 commit이전 sql문이 수행되고 commit만 남은 상태를 말한다.
Committed
트랜잭션 완료 상태. 트랜잭션이 정상적으로 완료된 상태를 말한다.
Aborted
트랜잭션이 취소 상태. 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태를 말한다.
Partially Committed 와 Committed 의 차이점
Commit 요청이 들어오면 상태는 Partial Commited 상태가 된다. 이후 Commit을 문제없이 수행할 수 있으면 Committed 상태로 전이되고, 만약 오류가 발생하면 Failed 상태가 된다. 즉, Partial Commited는 Commit 요청이 들어왔을때를 말하며, Commited는 Commit을 정상적으로 완료한 상태를 말한다.
트랜잭션을 사용할 때 주의할 점
트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다. 즉 트랜잭션의 범위를 최소화하라는 의미다. 일반적으로 데이터베이스 커넥션은 개수가 제한적이다. 그런데 각 단위 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어들게 된다. 그러다 어느 순간에는 각 단위 프로그램에서 커넥션을 가져가기 위해 기다려야 하는 상황이 발생할 수도 있는 것이다.
교착상태
복수의 트랜잭션을 사용하다보면 교착상태가 일어날수 있다. 교착상태란 두 개 이상의 트랜잭션이 특정 자원(테이블 또는 행)의 잠금(Lock)을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태가 되는데, 이를 교착상태라고 한다.
교착상태의 예(MySQL)
MySQL MVCC에 따른 특성 때문에 트랜잭션에서 갱신 연산(Insert, Update, Delete)를 실행하면 잠금을 획득한다. (기본은 행에 대한 잠금)
트랜잭션 1이 테이블 B의 첫번째 행의 잠금을 얻고 트랜잭션 2도 테이블 A의 첫번째 행의 잠금을 얻었다고 하자.
Transaction 1> create table B (i1 int not null primary key) engine = innodb;
Transaction 2> create table A (i1 int not null primary key) engine = innodb;
Transaction 1> start transaction; insert into B values(1);
Transaction 2> start transaction; insert into A values(1);
트랜잭션을 commit 하지 않은채 서로의 첫번째 행에 대한 잠금을 요청하면
Transaction 1> insert into A values(1);
Transaction 2> insert into B values(1);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Deadlock 이 발생한다. 일반적인 DBMS는 교착상태를 독자적으로 검출해 보고한다.