READ UNCOMMITED : 커밋 되지 않은 데이터에 다른 트랜잭션 접근 가능
정합성에 심각한 문제 발생하기에 사용 권장X
(부정합 문제) DIRTY READ : 커밋 이전에 변경된 데이터를 보고 있을때 트랜잭션이 롤백 된다면 현재 데이터가 잘못된 데이터로 되는 상태
- A TR 시작
- B TR 시작
- A TR : UPDATE SET name = '훈이' WHERE id = 1
- B TR : SELECT * FROM WHERE id = 1
- A TR Rollback
- A의 id가 1인 것의 name은 '훈이'가 아님
- B TR에서 select도 Rollback이 되거나 해야 문제가 발생 안함
- B TR COMMIT
- 하지만 B 커밋 -> 부정합 DIRTY READ 발생
READ COMMITTED : 커밋된 데이터에 다른 트랜잭션이 접근할 수 있음
커밋되지 않은 데이터에 접근할 시 undo 영역에서 가져옴
(부정합 문제) NON-REPEATABLE READ : 기존 데이터의 변경에 의해 하나의 트랜잭션 내에서는 동일한 select 쿼리를 날렸을 때 다른 결과가 나오는 문제
- B TR 시작
- B TR : SELECT * FROM tb WHERE id = 1
- id : 1 / name : 짱구
- A TR 시작
- A TR : UPDATE SET name = '훈이' WHERE id = 1
- B TR : SELECT * FROM tb WHERE id = 1
- 아직 A TR에서 변경 쿼리가 반영되지 않아 undo 영역에서 데이터를 읽어온다.
- id : 1 / name : 짱구 ('훈이' 가 아님)
- A TR : Commit
- 변경 사항 반영됨
- B TR : SELECT * FROM tb WHERE id = 1
- 이전 시점에 A가 commit을 통해 변경사항을 반영시켰기에 undo영역이 아닌 실제 테이블에서 참조
- id : 1 / name : 훈이('짱구' 가 아님)
- B TR : Commit
- NON-REPEATABLE 부정합 문제 발생했음
- 조회 결과가 항상 같아야 하는데 같지 않음
REPEATALE READ : 동일한 select 문을 날렸을 시 같은 결과를 보장 해야 함
- TR B 시작 (tx_id = 5)
- SELECT * FROM tb WHERE id = 1
- id : 1 / name : 신짱구 / tx_id : 3 (3번 TR에서 update 됐었음 표기)
- TR A 시작 (tx_id = 7)
- UPDATE tb SET name = '훈이' WHERE id = 1
- id : 1 / name : 훈이 / tx_id : 7(7번 TR에서 마지막 갱신)
- A TR Commit
- B TR : SELECT * FROM tb WHERE id = 1
- id : 1 / name : 신짱구 / tx_id : 3 (A TR은 7번으로 자신보다 높은 번호기에 Undo 영역에서 데이터를 읽어옴)
- B TR Commit
(부정합 문제) PANTHOM READ : 유령, 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 첫번째 selct에서 존재하지 않았던 것이, 2번째 select문에 결과로 나옴
- TR B 시작 (tx_id = 5)
- SELECT * FROM tb WHERE id > 1 FOR UPDATE
- id : 1 / name : 신짱구 / tx_id : 3
- id : 2 / name : 훈이 / tx_id : 3
- TR A 시작 (tx_id = 7)
- INSERT tb SET id = 3, name = '맹구'
- TR A Commit
- SELECT * FROM tb WHERE id > 1 FOR UPDATE
- SELECT ~ FOR UPDATE : select한 쿼리에 대해 쓰기 잠금
- Undo 영역에서는 쓰기 잠금을 걸 수 없기에 자신보다 높은 트랜잭션 번호를 가진 행일 지라도 조회가 됨
- 이전에 없던 데이터(팬텀 행) 나타남
- id : 1 / name : 신짱구 / tx_id : 3
- id : 2 / name : 훈이 / tx_id : 3
- id : 3 / name : 맹구 / tx_id : 7 (이전 쿼리에 없던 데이터(팬텀 행))
SERIALIZABLE : 가장 엄격한 격리 수준, 동시에 같은 행에 접근할 수 없음. 모든 부정합 문제 해결
- 한 트랜잭션이 끝날때까지 절대 접근 불가
- 동시 처리가 불가능함으로 권장X
DIRTY READ | NON-REPEATABLE READ | PHANTOM READ | |
---|---|---|---|
READ UNCOMMITTED | O | O | O |
READ COMMITED | O | O | |
REPEATABLE READ | O | ||
SERIALIZABLE |
READ UNCOMMITTED : 커밋이 되지 않은 데이터에 접근 가능하며 3가지 부정합 문제가 모두 발생
READ COMMITTED : 커밋이 된 데이터에만 접근할 수 있고 DIRTY READ의 부정합 문제 해결
REPEATABLE READ : 트랜잭션 번호가 자신보다 낮은 번호에만 접근 해서 NON REPEATABLE 문제를 해결 했으나 PHANTOM READ 부정합 문제가 발생
SERIALIZABLE : 가장 강력한 레벨로 모든 부정합 문제를 해결하지만 동시성이 매우 떨어짐
jpa 에서는 READCOMMITED로 기본값 사용