-
Transaction (트랜잭션)
- 여러 작업들을 하나로 묶은 단위이다.
- 때문에, 하나로 묶인 여러 작업들은 모두 실행 되거나, 모두 실행 되지 않거나 둘 중 하나이다.
- 트랜잭션의 성질
- (A) atomicity : 트랜잭션의 작업이 부분적으로 실행되거나 중단되지 않음을 보장한다.
- (C) consistency : int 타입 컬럼에 string 타입이 저장되지 않도록 보장한다.
- (I) isolation : 트랜잭션 수행 중에는 다른 트랜잭션이 끼어들지 않도록 보장한다.
- (D) durablility : 성공적으로 수행된 트랜잭션은 영원히 반영됨을 보장한다.
- 트랜잭션의 병행 처리 시 문제점
- 갱신 내용 손실
- 현황 파악 오류
- 모순성
- 연쇄 복귀 : 두 트랜잭션이 하나의 레코드를 갱신할 때, 하나의 트랜잭션이 롤백하면 다른 하나의 트랜잭션 마저 롤백되는 문제
- Database에서의 Deadlock (데드락)
- 두 트랜잭션이 무한적 대기해야하는 상황이 발생하는 것
- 해결 방법 : T1, T2 둘 중 하나를 Rollback하고 나머지 하나를 완료시킨 후, Rollback한 트랜잭션을 다시 실행
- 데드락 탐지 또는 회피 방법
- 탐지 : 매 순간 데드락인지 아닌지 검사를 해야하고, 이는 비용이 크다.
- 회피
- Master DB와 Slave DB로 나누어, 읽고 쓰는 기능을 분리한다.
- 트랜잭션 별 타임스탬프를 지정하여 순서를 미리 선택한다.
Transaction - Isolation Level (트랜잭션 - 격리 수준)
- 동시에 여러 개의 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회한 데이터를 볼 수 있도록 허용 여부를 결정하는 것
- 격리 수준의 필요성
- 기본적으로 트랜잭션은 ACID 성질을 가지고 있고, 특정 트랜잭션이 DB를 다루고 있을 때, 다른 트랜잭션의 개입을 막기 위해 'Locking'이라는 개념이 등장한다.
- 무조건적인 locking은 트랜잭션 간 ACID 성질을 유지할 수 있지만, DB 성능은 떨어진다.
- 반대로 여유로운 locking은 잘못된 값의 처리 등의 장애가 발생할 수 있다.
- 따라서 적절하고 효율적인 locking이 필요하다.
- 트랜잭션 격리 수준의 종류
- level 0 : READ UNCOMMITTED
- level 1 : READ COMMITTED
- level 2 : REPEATABLE READ
- level 3 : SELIALIZABLE
- 격리 수준 별 발생 가능한 현상
- Dirty Read : 트랜잭션의 작업이 완료되지 않았는데, 다른 트랜잭션에서 볼 수 있는 현상
- Non-Repeatable Read : 하나의 트랜잭션에서 같은 쿼리를 두 번 실행할 때, 두 결과가 다른 현상
- Phantom Read : 하나의 트랜잭션에서 같은 쿼리를 두 번 실행할 때, 첫 번째 결과에서 보지 못한 결과가 두 번째 결과에서 보이는 현상
level 0 : READ UNCOMMITTED
- 각 트랜잭션의 변경 내용이 COMMIT, ROLLBACK 여부와 관계 없이, 다른 트랜잭션의 값을 읽어올 수 있다.
- 데이터의 정합성에 대해 문제가 많이 발생하기 때문에, 사용하지 않는 것으로 권장된다.
level 1 : READ COMMITTED
- 대부분의 DB에서 사용하는 방식이다.
- Dirty Read가 발생하지 않는다.
- 실제 테이블의 값을 가져오는 것이 아니라, Undo 영역의 백업된 record 값을 가져온다.
- 하나의 트랜잭션에 대해 똑같은 SELECT문을 실행시킬 경우, 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋난다.
level 2 : REPEATABLE READ
- mySQL의 경우, 트랜잭션마다 각각의 트랜잭션 ID를 부여하여, 해당 ID보다 작은 트랜잭션 ID의 변경 내용만 가져온다.
- Undo 영역에 백업을 하고, 실제 record 값을 변경한다.
- 백업된 데이터는 필요없다고 판단될 시 주기적으로 삭제된다.
- Undo 영역에 백업된 데이터가 많아진다면, 성능 저하가 발생될 수 있다.
- 이러한 변경 방식을 MVCC(Multi Version Concurrency Control)이라고 부른다.
level 3 : SELIALIZABLE
- 가장 단순하고 가장 엄격한 격리 수준이다.
- 동시 처리 성능 측면에서 비효율적이다.
- Phantom Read가 거의 발생하지 않지만, DB에서 거의 사용되지 않는 수준이다.