-
MySQL - 트랜잭션 격리 수준 실습💻 computer science/📦 database 2024. 5. 11. 21:24
⚙️ 실습 세팅
트랜잭션 격리 수준을 실습해보기 위해서 테이블을 만들고 데이터를 넣어두었다.
👤 Member Table
CREATE TABLE MEMBER ( id bigint auto_increment primary key, name varchar(255) not null, constraint UK_name unique (name) );
➕ 데이터 추가
INSERT INTO MEMBER (id, name) VALUES(1, 'Beomsic'); INSERT INTO MEMBER (id, name) VALUES(2, 'Beomseok'); INSERT INTO MEMBER (id, name) VALUES(3, 'KO');
💻 2개의 데이터베이스 세션 설정
set autocommit = FALSE; // 현재 세션의 자동 커밋 비활성 SELECT @@tx_isolation; // 현재 세션 격리 수준 확인
각각의 세션에서 자동 커밋 모드를 꺼준다.
🧩 SERIALIZABLE
🔍 데이터 조회
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공START TRANSACTION; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공COMMIT; COMMIT; SERIALIZABLE 은 일반적인 SELECT 작업에서도 대상 레코드에 넥스트 키 락을 읽기 잠금으로 건다
따라서, 한 트랜잭션에서 읽은 레코드를 다른 트랜잭션에서도 조회할 수 있다.
🔄 데이터 수정
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공START TRANSACTION; UPDATE MEMBER SET name = ‘KOBEOMSEOK’ WHERE id = 3;
- 잠금 대기 상태 (A)COMMIT; (B) UPDATE 쿼리 실행 완료 COMMIT; 🔒 (A) 잠금 대기 상태
📍 COMMIT 이후 (B)
✔️ 결과
SELECT * FROM MEMBER WHERE id >= 3; // id : 3 name : KOBEOMSEOK
SERIALIZABLE 격리수준에서 한 트랜잭션이 읽은 데이터를 다른 트랜잭션에서 수정하는 것은 불가능하다.
- 이유 : 읽기 잠금에 의해 변경을 하기 위해서는 락을 획득해야 하기 때문
🧩 REPEATABLE READ
🏃 REPEATABLE READ 정상 작동
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공START TRANSACTION; UPDATE MEMBER SET name = ‘KO’ WHERE id = 3;
- 업데이트 성공COMMIT; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공
- name : KOBEOMSEOK(변경 전 데이터)REPEATABLE READ에서는 기본적으로 다른 트랜잭션에서 변경한 내용이 보이지 않는다.
👻 Phantom Read 발생 (부정합 문제)
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공START TRANSACTION; INSERT INTO MEMBER (id, name) VALUES (4, 'phantomname');
- 성공COMMIT; SELECT * FROM member WHERE id >= 3;
- 2건 조회 (MySQL 이 아닌 경우)
- 1건 조회 (MySQL)🧩 READ COMMITTED
🏃 READ COMMITTED 정상 작동
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; UPDATE MEMBER SET name = ‘KKK’ WHERE id = 3;
- 업데이트 성공SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공
- 변경 전 데이터COMMIT; SELECT * FROM member WHERE id >= 3;
- 1건 조회 성공
- name : KKK(변경 후 데이터)💣 Non-Repeatable Read 발생 (부정합 문제)
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; SELECT * FROM member WHERE name = ‘KOKO’
- 0건 조회 성공START TRANSACTION; UPDATE MEMBER SET name = ‘KOKO’ WHERE Id = 3;
- 성공COMMIT; SELECT * FROM member WHERE name = ‘KOKO’
- 1건 조회READ COMMITTED 에서 한 트랜잭션내에서 반복 읽기를 수행할 때, 다른 트랜잭션의 커밋 여부에 따라 조회 결과가 달라진다.
- Non-Repeatable Read
🧩 READ UNCOMMITTED
💣 Dirty Read 발생 (부정합 문제)
사용자 A 사용자 B SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION; SELECT * FROM member WHERE name = ‘KKK’
- 0건 조회 성공UPDATE MEMBER SET name = ‘KKK’ WHERE Id = 3;
- 성공SELECT * FROM member WHERE name = ‘KKK’
- 1건 조회READ COMMITTED 에서 한 트랜잭션내에서 반복 읽기를 수행할 때, 다른 트랜잭션의 커밋 여부에 따라 조회 결과가 달라진다.
- Non-Repeatable Read
📕 참고자료
[MySQL] 트랜잭션 격리 수준과 부정합 문제들(Dirty Read, Non-Repeatable Read, Phantom Read) 실습해보기
'💻 computer science > 📦 database' 카테고리의 다른 글
MySQL Full-Text Search 도입기 (0) 2025.04.14 MySQL - 스토리지 엔진 수준의 락 (0) 2024.05.11 📂 MySQL - 트랜잭션 격리 수준 (0) 2024.05.11 인덱스 (0) 2022.10.05 SQL / NoSQL (1) 2022.10.05