-
Transaction이란 무엇인가?
- 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 or 한번에 모두 수행돼야하는 연산들을 의미
- 작업의 완전성을 보장해준다. 논리적인 작업을 모두 완벽히 처리하거나 처리하지 못할 경우에는 원 상태로 복구해서 작업의 일부만 적용되는 현상이 발생되지 않게 만들어준다.
- 트랜잭션과 Lock
- Lock은 동시성을 제어하기 위한 기능, 트랜잭션은 정합성을 보장하기 위한 기능
- Lock은 여러 커넥션에서 동시에 동일 자원에 대해 자원을 요청할 때 순서대로 하나의 커넥션만 변경할 수 있게 해주는 역할
- 트랜잭션은 쿼리의 갯수에 관계 없이 논리적인 작업 셋 자체가 100% 적용되거나 아무것도 적용되지 않아야함을 보장
- 특징 (ACID)
- 원자성(Atomicity)
- 트랜잭션 중간에 문제가 발생하면 해당하는 어떠한 작업도 수행되어서는 안되며 아무 문제가 없을 때만 모든 작업이 수행되어야함
- 일관성(Consistency)
- 트랜잭션이 완료된 다음 상태도 트랜잭션이 일어나기 전과 같은 일관성을 보장해야함
- 고립성(독립성) (Isolation)
- 지속성(Durability)
- 트랜잭션이 정상적으로 종료되면 영구적으로 DB에 결과가 저장돼야함
- 상태
- 활동(Active)
- 철회(Aborted)
- 트랜잭션이 취소된 상태, 트랜잭션이 취소되고 실행되기 이전으로 돌아간 상태
- 부분 완료(Partially Committed)
- 트랜잭션의 commit이 도착한 상태, sql문이 수행되고 커밋만 남은 상태 (sql문에서 문제가 발생하면 Failed, 정상적으로 실행되면 Commited)
- 실패(Failed)
- 트랜잭션 실패 상태, 더 이상 정상 진행이 불가능한 상태
- 완료(Commited)
- 트랜잭션 사용 시 주의할 점
- 꼭 필요한 최소 코드에만 적용하는 것이 좋음(범위 최소화)
- 일반적으로 커넥션은 개수가 제한적 ~> 각 프로그램이 커넥션을 소유하는 시간이 길어지면 대기시간이 길어지는 상황 발생
- 복수의 트랜잭션을 사용하면 교착상태 발생(두 개 이상의 트랜잭션이 특정 자원에 대한 Lock을 가지고 다른 트랜잭션이 소유하고 있는 Lock을 요구할 때 발생)
- 빈도를 낮추는 방법
- 트랜잭션을 자주 커밋한다
- 정해진 순서로 테이블에 접근
- 읽기에 대한 잠금 획득은 사용 자제
- Isolation Level (격리 수준)
- 트랜잭션에서 일관성이 없는 데이터를 허용하도록 하는 수준
- == 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 고립되어 있는지 표현
- 격리 수준
- 아래 4가지 (아래로 갈수록 고립이 높아짐 ~> 성능이 떨어짐)
- READ UNCOMMITTED
- 어떤 트랜잭션의 변경내용이 COMMIT이나 ROLLBACK과 상관없이 다른 트랜잭션에서 보여진다.
- DIRTY READ PROBLEM
- READ COMMITTED
- Oracle 채택
- 어떤 트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회할 수 있다.
- NON-REPETABLE READ 부정합 문제 발생
- 항상 같은 값을 반환하지 않는다. (commit 전과 후에 read하면 값이 다름)
- REPEATABLE READ
- MySQL 채택
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리수준
- read에 부정합이 없음
- 하지만 update 부정합과 Phantom READ(첫 쿼리에서 없던 레코드가 발견)이 있음
- 없는 값을 읽었다.(잘못된 값을 읽었다)
- 부캠 루카스 수업 자료를 참고하자
- 하지만, 극히 드물다 라고 하셨음 (mysql에서는 확인이 불가)
- SERIALIZEABLE
- 가장 단순하고 가장 엄격한 격리 수준
- 읽기 작업에서도 공유 잠금을 하는데, 성능 저하가 발생
- 다른 트랜잭션이 끝날때 까지 대기함
- 읽기는 모든 트랜잭션 다 되지만 2번째로 시작한 트랜잭션부터는 수정이 불가능하다.
- 첫 트랜잭션에서 수정작업이 일어나면 다른 트랜잭션에서 읽기도 불가능해짐
- 필요한 상황이 거의 없다.