"데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위"
트랜잭션은 총 4가지 특성이 있다
이 중 격리에 대해서 중점으로 알아보도록 하자
"실행 중인 트랜잭션의 중간결과를 다른 트랜잭션이 접근할 수 없다."
하지만 데이터베이스는 실시간 접근
, 동시 공유
라는 특성을 가지고 있다.
즉 우리는 데이터베이스에 대해서 동시성을 고려할 수 있어야 된다는 것이다.
트랜잭션은 그에 맞게 격리 수준을 제공하고 있다.
Read Uncommited
는 카밋이 완료되지 않은 다른 트랜잭션의 결과에 접근 할 수 있음. 하지만 Dirty Read 등 여러가지 데이터 부정합 문제가 발생할 수 있음.
커밋되지 않는 데이터를 읽는 데이터 부정합 문제
A와 B라는 트랜잭션이 있을 때
Transaction1
은 (222, Busan)인 Row를 Insert 하였다. (카밋 미 완료)
Transaction2
는 조회시 (222, Busan)의 로우를 읽을 수 있음.
문제는 만약 Transaction1
이 문제가 생겨 Rollback이 된다면 Transaction2
는 잘못된 데이터를 조회한 것이 되는 것이다.
Read Commited
는 커밋된 트랜잭션에만 다른 트랜잭션이 접근할 수 있음.
Dirty Read를 해결하기 위해서 Undo 영역을 도입하였음.
Undo
영역은 데이터에 변경이 있을 경우 이전의 데이터를 보관하는 곳임
하지만 Non-Repeatable Read 문제를 해결하지 못하였음.
한 트랜잭션 내에서 같은 Key를 가진 Row를 두 번 읽었는데 그 사이에 값이 변경되어 결과가 다르게 나타나는 현상
Transaction1
은 (222, Jeju)인 Row를 (222, Busan)으로 Update 하였다. (카밋 미 완료)
Transaction2
는 조회시 Undo 영역에 있는 (222, Jeju)의 로우를 읽음
Transaction1
은 트랜잭션 결과를 카밋하였음
Transaction2
는 조회시 (222, Busan)의 로우를 읽음
문제는 하나의 트랜잭션은 같은 쿼리문에 대해 동일한 결과를 반환해야 하지만 동일한 Row의 동일한 결과를 반환하지 못함.
Reapeatable Read
는 트랜잭션마다 트랜잭션 ID가 존재하는데 자신보다 낮은 트랜잭션 ID를 가진 값만 조회할 수 있게 하면서 Non-Reapeatable Read
문제를 해결하였다.
하지만 Phantom Read 문제는 해결하지 못하였음.
한 트랜잭션 내에서 같은 쿼리를 두 번 수행했는데, 첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상
A와 B라는 트랜잭션이 있을 때
B트랜잭션이 데이터를 조회 후 1, 2번 로우를 읽었다.
A트랜잭션이 데이터를 2개를 추가해 3, 4번 로우가 생성 (커밋 완료)
B트랜잭션은 데이터 조회시 1, 2, 3, 4번 로우를 읽게 된다.
문제는 하나의 트랜잭션은 같은 쿼리문에 대해 동일한 결과를 반환해야 하지만 동일한 결과를 반환하지 못하는 데이터 정합성의 문제가 있다.
https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation