[데이터베이스] 트랜잭션(Transaction)
트랜잭션
- 데이터베이스 상태를 변화시키는 하나의 논리적인 작업 단위를 구성하는 연산의 집합
- 하나의 트랜잭션은 Commit되거나 Rollback되어야한다.
1) Commit 연산
- 트랜잭션에 대한 작업이 성공적으로 끝났을 때 수행
- 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산
2) Rollback 연산
- 트랜잭션 처리가 비정상적으로 종료되었을 때 수행
- 트랜잭션의 원자성을 구현하기 위해 트랜잭션이 행한 모든 연산은 취소하는 연산
3) Lock과 트랜잭션
(1) Lock
- 여러 Connection에서 동시에 동일한 자원을 요청할 경우, 한 시점에 하나의 Connection만 변경할 수 있도록 해주는 역할
- 동시성 제어
(2) 트랜잭션
- 하나의 논리적인 작업 셋 자체가 100% 적용되거나 아무것도 적용되지 않아야함을 보장
- 데이터의 정합성을 보장
3) 트랜잭션의 특징(ACID)
(1) 원자성(Atomicity)
- 트랜잭션의 모든 연산은 정상적으로 수행 완료되거나 아니면 어떤 연산도 수행되지 않는 것을 보장
- All or nothing
- 회복
(2) 일관성(Consistency)
- 트랜잭션이 완료된 다음의 상태에서도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장
- 동시성 제어, 무결성 제약조건
(3) 독립성(Isolation)
- 하나의 트랜잭션이 실행되는 도중에 변경한 데이터는 트랜잭션이 완료될 때까지 다른 트랜잭션이 참조하지 못하는 것을 보장
- 동시성 제어
(4) 지속성(Durabiliy)
- 트랜잭션이 정상적으로 종료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 저장되어야 함
- 회복
4) 트랜잭션의 상태
(1) 활동(Active)
- 트랜잭션이 연산을 실행 중인 상태
(2) 장애(Failed)
- 트랜잭션 실행에 오류가 발생해 중단된 상태
(3) 부분 완료(Partially Committed)
- 트랜잭션이 마지막 연산까지 수행하고 Commit 연산이 실행되기 직전의 상태
(4) 완료(Committed)
- 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태
(5) 철회(Aborted)
- 트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태
5) 트랜잭션 시 주의할 점
- 데이터베이스 Connection 개수가 제한적이기 때문에 트랜잭션의 범위를 최소화
- Conntection을 소유하는 시간이 길어질수록 사용가능한 Connection 수는 줄어듬
6) 교착상태
- 두 개 이상의 트랜잭션이 특정 자원의 잠금을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하여 아무리 기다려도 상황이 바뀌지 않는 상태
(1) 교착상태의 빈도를 낮추는 방법
- 트랜잭션을 자주 Commit
- 정해진 순서대로 테이블에 접근
- 읽기 잠금 획득 사용을 피함
- 테이블 단위의 잠금을 획득해 갱신을 직렬화(동시성이 떨어지지만 교착상태를 줄일 수 있음)
트랜잭션 격리 수준(Transaction Isolation Level)
- 트랜잭션에서 일관성 없는 데이터를 허용하도록 하는 수준
- 특정 트랜잭션이 다른 트랜잭션에서 변경한 데이터를 접근을 허용하는 수준
- 데이터베이스는 트랜잭션이 원자적이면서 독립적으로 수행되기 위해 Lock을 사용
- 무조건적인 Lock은 동시성을 제어하므로 데이터베이스의 성능을 떨어뜨리고, 반대로 Lock 범위를 줄인다면 데이터의 정합성을 보장하기 어려움
- 격리 수준이 높아질수록 비용이 높고 동시성이 떨어지지만, 데이터 무결성을 유지할 수 있음
- 최대 효율의 Lock 방법이 필요
1) Read Uncommitted(Level 0)
- 특정 트랜잭션의 변경 내용을 Commit과 Rollback에 상관없이 다른 트랜잭션이 접근 가능
- 트랜잭션이 처리 중인 혹은 아직 Commit 되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용하는 격리 수준
- 데이터의 일관성을 유지 할 수 없음
- Dirty Read, Non-Repeatable Read, Phantom Read 발생
2) Read Committed(Level 1)
- 특정 트랜잭션의 변경 내용이 Commit되어야만 다른 트랜잭션에서 접근 가능
- 트랜잭션이 수행되는 동안 다른 트랜잭션은 접근할 수 없어 대기
- Non-Repeatable Read, Phantom Read 발생
- Orable DB, SQl Server에서 Default로 사용하는 격리 수준
3) Repeatable Read(Level 2)
- 트랜잭션이 시작되기 전에 Commit된 내용에 대해서만 조회 가능(Undo 백업 영역에 저장됨)
- 다른 사용자는 그 영역에 해당하는 데이터에 대한 수정 불가능
- 트랜잭션이 범위 내에서 조회한 데이터의 내용이 항상 동일함을 보장
- Phantom Read 발생
- MySQL에서 Default로 사용하는 격리 수준
4) Serializable(Level 3)
- 가장 엄격한 격리 수준
- 다른 사용자는 그 영역에 해당하는 데이터에 대한 수정 및 입력 불가능
- 완벽한 읽기 일관성 모드 제공
트랜잭션 격리 수준에서 발생하는 현상
1) Dirty Read
- 유효하지 않은 데이터를 읽어들임
- Commit되지 않은 수정 중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생
2) Non-Repeatable Read
- 한 트랜잭션에서 같은 Query를 두 번 수행할 때, 두 Query의 결과가 상이하게 나타나는 현상
- 특정 트랜잭션이 접근하고 있는 데이터를 다른 트랜잭션이 수정 또는 삭제하므로써 발생
3) Phantom Read
- 일정 범위의 레코드를 두 번이상 읽을 때, 이전에 없던 유령 레코드가 나타나는 현상
- 특정 트랜잭션이 작업 도중 다른 트랜잭션이 새로운 레코드를 삽입하는 것을 허용하기 때문에 발생
Isolation Level | Dirty Read | Non-Reapeatable Read | Phantom Read |
Read Uncommitted | O | O | O |
Read committed | - | O | O |
Repeatable Read | - | - | O |
Serializable | - | - | - |