트랜젝션 격리 수준이란?
특정 트랜잭션이 다른 트랜잭션에 의해 변경된 데이터를 볼 수 있도록 허용할지 여부를 결정하는 것이다.
격리수준은 4개로 나뉜다
- READ-UNCOMMITTED
- READ-COMMITTED
- REPEATABLE-READ
- SERIALIZABLE
아래로 내려갈수록 고립 정도가 높아진다
고립정도가 높아진다는 의미는 단순하고 엄격해짐을 의미한다. SERIALIZABLE 수준잉 되면 SELECT를 하는것만으로도 잠금(LOCK)을 설정되어 다른 트랜잭션에서 이 레코드를 전혀 변경하지 못하게 된다. 데이터 정합성은 좋아지겠지만 문제는 성능저하가 높아진다는 것이다.
일반적인 온라인 서비스에서는 READ COMMITTED와 REPEATABLE READ를 사용한다.
오라클의 경우 기본값은 READ COMMITTED이, MYSQL의 경우 REPEATABLE READ가 기본값이다.
ISOLATION LEVEL을 조회하는 방법은 다음과 같다
SHOW VARIABLES like 'tx_isolation';
각 설정에 따른 것을 좀더 상세히 알아보자
# READ-UNCOMMITTED
다른 트랜잭션의 변경내용이 Commit이나 Rollback과 상관없이 보여지는 상태다. Dirty Read를 유발하며 데이터 정합성 문제가 많 때문에 RDBMS에선 격리수준으로 인정하지 않을 정도다. 일반적으로 거의 사용하지 않는다.
# READ-COMMITTED
Commit이 완료된 데이터만 다른 트렌잭션에서 조회할 수 있다. 아직 Commit되기 전이라면 다른 트랜잭션은 undo영역에 있는 이전 값을 참고하여 보여준다.
Oracle에서 기본으로 사용되고 있는 격리수준이다
# REPEATABLE-READ
모든 데이터에 shared lock이 걸리며, 다른 사용자는 해당 영역 데이터 수정이 불가능하다.
Binary Log를 가진 Mysql 장비에서는 최소 이 단계의 격리 수준 이상을 사용함을 권장한다.
Commit하지 않는다면 undo 영역에 백업된 데이터를 보여준다. 만약 트랜잭션을 종료하지 않는다면 undo영역이 무한정 커질 수 있다. 하지만 실제로 영향을 미칠정도로 오래 지속되는 경우는 잘 없다.
참고로 1번 트랜잭션이 update문을 수행하고 아직 commit하기 전이라 할때, 2번 트랜잭션이 접근되어 update문을 수행할 경우 쓰기잠금을 할 수 없는데, 이유는 undo에 있는 영역에서 조회해온 데이터이기 때문이다.
Mysql에서 기본으로 사용되고 있는 격리수준이다
# SERIALIZABLE
거의 사용하지 않는 설정
단순 SELECT를 할때에도 공유 잠금(읽기 잠금)을 획득해야 하며, 다른 트랜잭션은 그 레코드를 변경할 수 없다.
# 기타
Mysql에서 기본값이 REPEATABLE-READ으로 되어있다보니 개발을 어떻게 하느냐에 따라 다음의 에러가 발생할 수 있다.
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
그래서 오라클과 마찬가지 단계인 READ-COMMITTED으로 설정하는 경우도 있다.
'공부 > 프로그래밍' 카테고리의 다른 글
[mysql] REPEATABLE-READ에서 dead lock이 걸린 이유 (0) | 2020.04.09 |
---|---|
[spring oauth2 ResourceServer] oauth2 에서 CORS 설정 테스트 (0) | 2020.04.04 |
[querydsl, mysql] DATE_FORMAT 등 이용해 groupby 사용하기 (0) | 2020.04.02 |
[springboot, oauth] Resource Server(자원서버) 구축하기 (0) | 2020.03.29 |
[springboot, oauth] Authorization Server(인증서버) 구축하기 (2) | 2020.03.21 |
댓글