-
MariaDB IsolationDatabase 2023. 4. 1. 14:34
Isolation Level
- READ UNCOMMITTED
이 격리 레벨에서는 커밋되지 않은 데이터에 대한 읽기 작업도 허용됩니다. 따라서 다른 트랜잭션에서 변경 작업을 수행하는 동안, 해당 데이터에 대한 읽기 작업을 수행하면 변경 작업의 결과를 볼 수 있습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성이 보장되지 않으므로 사용하지 않는 것이 좋습니다. - READ COMMITTED
이 격리 레벨에서는 커밋된 데이터만 읽을 수 있습니다. 따라서 다른 트랜잭션에서 변경 작업을 수행하는 동안, 해당 데이터에 대한 읽기 작업을 수행하면 변경 작업의 결과를 볼 수 없습니다. 이 격리 레벨은 데이터 일관성과 무결성을 보장하면서도, 동시성을 높일 수 있어서 가장 많이 사용되는 격리 레벨 중 하나입니다. - REPEATABLE READ
이 격리 레벨에서는 한 트랜잭션 내에서 같은 쿼리를 실행하는 경우, 항상 동일한 결과를 반환합니다. 따라서 다른 트랜잭션이 데이터를 변경하더라도, 해당 트랜잭션에서는 변경된 데이터를 읽지 않습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성을 보장하면서도, 응답 시간을 높일 수 있습니다. - SERIALIZABLE
이 격리 레벨에서는 트랜잭션들이 서로 영향을 끼치지 않도록 모든 데이터에 대한 LOCK을 적용합니다. 따라서 동시성은 낮아지지만 데이터 일관성과 무결성을 가장 완벽하게 보장할 수 있습니다. 이러한 이유로 이 격리 레벨은 데이터 일관성과 무결성이 매우 중요한 상황에서 사용됩니다.
READ COMMITTED와 REPEATABLE READ 테스트
격리레벨에 따라서 트랜잭션 내에 조회 한 데이터가 어떤 결과를 가지고 오는지
가장 많이 사용하는 격리레벨인
READ COMMITTED와 REPEATABLE READ에서 테스트 해보겠습니다.READ COMMITTED 테스트
다른 트랜잭션에서 커밋한 내용을 읽어 오는지 확인해 보겠습니다.
-- T1 BEGIN; SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey -- T2 BEGIN; UPDATE users SET first_name = 'Kelsey2' WHERE id = 1; commit; SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey2 -- T1 -- SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey2 -- 아직 T1이 종료되지 않은 상태인데 T2에서 Commit한 변경사항을 T1에서 불러옵니다. -- 이렇게 되면, 하나의 트랜잭션내에서 동일한 쿼리를 실행 했을 때 -- 어느 순간 조회하느냐에 따라 다른 값을 불러올수 있게 됩니다.
REPEATABLE READ 테스트1
다른 트랜잭션에서 커밋한 내용이 반영되는지,
동일한 쿼리가 동일한 결과를 반환하는지 확인해 보겠습니다.-- T1 BEGIN; SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey -- T2 BEGIN; UPDATE users SET first_name = 'Kelsey2' WHERE id = 1; commit; SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey2 -- T1 SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey -- REPEATABLE READ는 하나의 트랜잭션내에서 하나의 쿼리를 실행할 때 동일한 결과를 반환합니다. -- 그렇기 때문에 T2에서 first_name을 Kelsey2로 바꿨지만, -- T1이 처음 실행했던 쿼리 결과인 Kelsey 를 반환하게 됩니다.
REPEATABLE READ 테스트2
여기서 한번, 색다르게 테스트 해보겠습니다.
트랜잭션만 시작하고 한번도 쿼리하지 않은 경우
다른 트랜잭션 내에서의 커밋한 내용이 반영되는지 보시겠습니다.-- 현재 id = 1의 first_name 값 Kelsey -- T1 BEGIN; -- T2 BEGIN; UPDATE users SET first_name = 'Kelsey2' WHERE id = 1; commit; SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey2 -- T1 SELECT first_name FROM users WHERE id = 1 ; -- 결과 : Kelsey2 -- T1을 시작할 때 id = 1의 first_name 값은 Kelsey 였습니다. -- 이후, T2에서 Kelsey2로 변경사항을 commit하게 되면, -- T1은 Kelsey가 아닌 T2에서 변경한 값 Kelsey2로 결과를 반환하게 됩니다. -- 이유는 한 트랜잭션 내에서 같은 쿼리를 실행하는 경우, 항상 동일한 결과를 반환할 뿐이지, -- 트랜잭셔 시작 시 한번도 쿼리하지 않은 결과를 가지고 있는 것은 아니기 때문입니다.
'Database' 카테고리의 다른 글
Phantom Rows (0) 2024.08.06 MariaDB Lock(이론) (0) 2023.04.01 MariaDB Lock(실전) (0) 2023.04.01 MariaDB Index 1편 (0) 2023.03.20 HikariCP 설정 일부분 들여다 보기 (0) 2023.02.26 - READ UNCOMMITTED