728x90
- 개인적으로 아키텍처 부분보다 역시 트랜잭션 부분이 더 재밌는거 같다...
- 트랜잭션 특성 ACID
- 트랜잭션 격리수준(Isolation Level)이란 여러 트랜잭션이 동시에 처리될 대 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 말지는 결정 하는 것.
- 격리 수준은 크게 아래와 같이 4가지로 나뉠 수 있다.
- READ UNCOMMITTED(커밋되지 않은 읽기)
- READ COMMITTED(커밋된 읽기)
- REPEATABLE READ(반복 가능한 읽기)
- SERIALIZABLE(직렬화 가능)
- 4개의 격리 수준에서 순서대로 뒤로 갈수록 각 트랜잭션 간의 데이터 격리(고립) 정도가 높아지며, 동시 처리 성능도 떨어지는 것이 일반적으로 볼 수 있다.
격리 수준 | DIRTY READ | NON-REPEATABLE READ | PHANTOM READ |
READ UNCOMMITTED | 발생 | 발생 | 발생 |
READ COMMITTED | 없음 | 발생 | 발생 |
REPEATABLE READ | 없음 | 없음 | 발생(InnoDB는 발생 없음) |
SERIALIZABLE | 없음 | 없음 | 없음 |
- -
- DIRTY READ(불완전 읽기):
- 트랜잭션 t1이 트랜잭션 t2 가 수정중인 데이터를 읽는 경우 t2 의 작업이 취소 되어도 t1은 이미 읽어들이 데이터를 가지고 있어서 불완전한 데이터를 사용할 수 있다.
- 즉 어떤 트랜잭션에서 처리한 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상
- NON-REPEATABLE READ(불가중복 읽기)
- t1이 같은 데이터를 두번 읽을때 t2에 의해 데이터가 수정되어 같은 데이터를 두 번 읽는 결과가 다를 수 있다.
- 하나의 트랜잭션에서는 동일데이터를 읽어야 한다
- Phantom Read (팬텀 읽기)
- t1이 같은 조건에서 두번 쿼리를 실행했을 때 사이에 다른 t2에 의해 새로운 데이터가 추가되어 같은 조건에서 두번 쿼리의 결과가 다를 수 있다.
- select 문에서 나타날 수 있으며, 쿼리로 읽힌 데이터에 새로 생기거나 없어지는 현상, 그래서 유령 읽기라 하는듯.
- DIRTY READ(불완전 읽기):
- SQL-92 또는 SQL-99 표준에 따르면 REOEATABKE READ 격리수준에서는 PHANTOM READ 가 발행할 수 있지만
InnoDB 에서는 독특한 특성 때문에 PHANTOM READ 가 일어나지 않는다.- SQL-92 또는 SQL-99 표준
- SQL-92(SQL2)와 SQL-99(SQL3)는 관계형 데이터베이스 관리 시스템에서 사용되는 구조화 질의 언어(SQL)의 국제 표준이다.
- SQL-92 또는 SQL-99 표준
- READ UNCOMMITTED
- 가장 낮은 격리 수준
- 각 트랜잭션에서의 변경 내용이 commit, rollback 여부에 상관없이 다른 트랜잭션에서 보인다.
- READ COMMITTED
- 더티리드가 발생되지 않는다.
- 트랜잭션에서 데이터를 변경했더라도 commit이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
- t1 트랜잭션이 commit 이전의 데이터 A 와 commit 후 변경된 데이터 B 를 읽어올 수 있기에 NON-REPEATABLE READ 부정합의 문제가 있다.
- REPEATABLE READ
- InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준
- 바이너리 로그를 가진 Mysql 서버에서는 최소 REPEATABLE READ 격리 수준 이상을 사용해야 한다.
- Innodb 스토리지 엔지에서 트랜잭션의 rollback 가능성에 대비해 변경되기전 언두 로그에 백업후 실제 레코드 값을 변경하는 MVCC 방식을 채택하고 있기 때문에, NON-REPEATABLE READ 이 발생하지 않는다.
- REPEATABLE READ는 이 MVCC를 위해 언두 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
- 기타: READ COMMITTED 도 MVCC를 이용해 commit 되기 전의 데이터를 보여주지만 언두 영역에 백업된 레코드의 여러 버전 가운데 몇 번째 이전 버전까지 찾아 들어가야 하느냐에 있다.
- 모든 Innodb 트랜잭션은 고유한 트랜잭션 번호를 가지며, 언두 영역에 백업된 모든 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함된다.
- 언두 영역에 백업된 데이터는 Innodb 스토리지 엔진이 불필요하다고 판단하는 시점에 주기적으로 삭제한다.
- MVCC 를 보장하기 위해 실행 중인 트랜잭션 가운데 가장 오래된 트랜잭션 번호보다 트랜잭션 번호가 앞선 언두 영역의 데이터는 삭제할 수 없다.
- 특정 트랜잭선 번호의 구간 내에서 백업된 언두 데이터가 보존돼야 한다.
- begin 명령으로 트랜잭션을 시작하면 트랜잭션 번호를 부여받는데, 그때부터 사용자 트랜잭션 안에서 실행되는 모든 select 쿼리는 부여받은 번호보다 작은 트랜잭션 번호에서 변경한 것만 보게 된다.
- 언두 레코드에서는 쓰기 잠금을 걸 수 없다.
- InnoDb 는행레벨 잠금 을 지원하기 때문에 여러 트랜잭션이 동시에 같은 행을 업데이트 하는 경우에도 충돌이 발생하지 않도록 하며, PHANTOM READ 현상을 방지한다.
- REPEATABLE READ 격리 수준에서는 트랜잭션이 시작되면 트랜잭션 내에서 사용되는 모든 데이터는 읽기 잠금으로 잠긴다.
- 이로인해 트랜잭션 내에서 데이터가 변경되어도 다른 트랜잭션에서 해당 데이터를 읽어 올때 변경 전의 데이터를 읽어 오게 된다.
- SERIALIZABLE
- 가장 단순하면서 가장 엄격한 격리수준
- select 를 포함한 모든 쿼리에 대해 잠금을 획득 해야한다.
728x90
'공부 > Mysql' 카테고리의 다른 글
[RealMysql 8.0] 인덱스 8 ~ 8.3.3.4 (0) | 2023.02.05 |
---|---|
[RealMysql 8.0] 데이터 압축 6 ~ 7.5.3 (0) | 2023.02.05 |
[RealMysql 8.0]5 트랜잭션과 잠금 5.3 ~ 5.3.3 (0) | 2023.02.05 |
mysql 트랜잭션 잠금 확인 쿼리. (0) | 2023.02.05 |
[RealMysql 8.0]5 트랜잭션과 잠금 네임드락 5.2.3 ~ 5.2.4 (0) | 2023.02.04 |
댓글