트랜잭션은 MySQL 의 작업의 완전성을 보장해주는 단위이다. 쿼리문을 실행하다가 에러가 발생하면 이전까지 작업하던 내용을 롤백시키거나 작업이 완료되면 작업 내용을 커밋시키는 등 MySQL 의 원자성을 보장해주는 단위이다.
트랜잭션에는 ACID 라고 하는 네 가지 속성이 있다.
Atomicity(원자성) 은 트랜잭션의 정의와 같다. 트랜잭션 내에 정의된 내용을 모두 적용하거나 적용하지 않는다는 속성이다. 에러가 발생할 경우 트랜잭션에 정의한 모든 과정들은 롤백되고, 성공적으로 작업을 마쳤을 경우 모든 내용이 올바르게 적용된다.
Consistency(일관성) 은 트랜잭션이 성공적으로 이루어졌을 때 트랜잭션 전의 상태와 커밋된 이후의 상태가 일관적이어야 한다는 속성이다. 예를 들어 테이블에 정의한 타입이 커밋된 이후에도 변경되지 않고 동일한 타입으로 남아있는 것이다.
Isolation(격리성) 은 두 개 이상의 트랜잭션이 서로 독립적으로 수행되어야 한다는 속성이다. 격리성에서 ‘격리’ 의 기준은 여러 개의 격리 수준으로 정의될 수 있다.
Durability(지속성) 은 트랜잭션이 성공적으로 이루어지면 반영된 내용은 시스템 내부적으로 에러가 발생하더라도 영구적으로 지속되도록 보장하는 속성이다.
트랜잭션의 속성 중 격리성에 대해 4단계로 나누어볼 수 있다.
READ UNCOMMITTED
커밋되지 않은 내용을 읽을 수 있는 단계이다.
이처럼 어떤 트랜잭션에서 처리한 작업이 완료되지 않아도 다른 트랜잭션에서 볼 수 있는 현상을 Dirty read(더티리드)라고 한다.
READ COMMITTED
커밋된 내용을 읽을 수 있는 단계이다. 트랜잭션이 진행중일 때 수정된 내용은 언두 로그에 저장되어 다른 트랜잭션에서 수정된 데이터에 접근하면 언두 로그의 데이터를 조회한다.
하지만 트랜잭션이 진행중일 때 다른 트랜잭션이 커밋되면 다른 트랜잭션의 변경 사항이 적용된 내용을 볼 수 있게 된다.
REPEATABLE READ
하나의 트랜잭션 내에서 반복 읽기가 가능한 단계이다. READ COMMITTED 단계에서는 트랜잭션 도중에 데이터를 수정하면 반복적으로 읽었던 데이터의 불일치가 발생했지만 REPREATABLE READ 단계에서는 이러한 불일치를 해결한다.
REPEATABLE READ 도 READ COMMITTED 와 마찬가지로 언두로그 영역에 있는 데이터를 조회한다. 하지만 언두로그 영역의 데이터를 조회할 때 읽는 범위의 차이가 있다. REPEATABLE READ 는 현재 트랜잭션 이전에 발생한 트랜잭션의 변경사항만 읽도록 설계되어 있다.
하지만 REPEATABLE READ 에서도 부정합이 발생할 수 있다.
데이터를 조회할 때 레코드에 쓰기 잠금을 걸어야 하는데 언두 레코드에는 잠금을 걸 수 없다. 따라서 조회할 때 언두 영역이 아닌 현재 레코드의 값을 가져와 이전에는 없던 데이터가 포함되는 것이다.
SERIALIZABLE
한 트랜잭션에서 읽고 쓰는 레코드에 대해 다른 트랜잭션이 절대 접근할 수 없는 단계이다. 가장 엄격한 격리수준이기 때문에 이전에 발생했던 문제들이 발생하지 않지만 InnoDB 스트리지 엔진에서는 갭락과 넥스트 키락 덕분에 REPEATABLE READ 격리 수준에서도 PHANTOM READ 가 발생하지 않아 굳이 사용할 필요가 없다.
참고 사이트