728x90
트랜잭션을 테스트 해보기 위해서 다른 SQL편집기를 열어서 테스트 해야한다.
테스트 방법
- START TRANSACTION;
- 트랜잭션을 실행한다.
- QUERY문 실행
- SELECT .... FOR UPDATE를 해야 쓰기락이 걸린다.
- 완료후 COMMIT한다.
트랜잭션 및 락 상태 확인
- 락 상태 확인
-
SELECT * FROM performance_schema.data_locks WHERE LOCK_TYPE = 'RECORD';
- 여러 ROW가 출력되는 이유는 여러 락이 동시에 잡혀서 그런다.
- LOCK_MODE가 X 는 쓰기락이 잡혀있다라는 뜻이다.
- INDEX_NAME : 어느 인덱스에 락이 잡혀있는지 출력된다.
- LOCK_DATA : Index VALUE
-
- 트랜잭션이 상태 확인
SELECT * FROM information_schema.innodb_trx;
테스트 코드
트랜잭션 1
START TRANSACTION;
SELECT *
FROM POST p
WHERE p.memberId = 2
AND p.contents = 'v'
FOR UPDATE;
COMMIT;
설명
-- START TRANSACTION;는 실행하고
SELECT *
FROM POST p
WHERE p.memberId = 2
-- COMMIT;은 테스트가 종료 될때까지 실행하지 않는다.
위코드를 출력 했을때는 4개의 ROW가 출력이된다.
하지만
AND p.contents = 'b'
를 붙이면 2개의 ROW만 출력이된다.
이때 FOR UPDATE;를 붙이고 실행을 한후 트랜잭션 2에서 같은 QUERY를 실행하면 계속해서 READ 시도를 한다.
- 중요!!
- 이때 출력된 2개 ROW말고 출력되지 않는 ROW의 Index를 가지고 SELECT 해도 출력이 되지 않는다.
- 출력은 2개이지만 Index에 모두 락이 걸리니 실질적으로 memberId가 2인 모든 ROW에 락이 걸려 있다
- 이때 출력된 2개 ROW말고 출력되지 않는 ROW의 Index를 가지고 SELECT 해도 출력이 되지 않는다.
혹시 모르니 테스트 할때 코드를 올린다.
트랜잭션1
-- 트랜잭션 1
START TRANSACTION;
-- 출력은 2개가 출력이 되나
-- Index에 모두 락이 걸리니 실질적으로 memberId가 2인 모든 ROW에 락이 걸려 있다.
SELECT *
FROM POST p
WHERE p.memberId = 2
AND p.contents = 'v'
FOR UPDATE;
COMMIT;
-- 락 상태 확인
-- 여러 ROW가 출력되는 이유는 여러 락이 동시에 잡혀서 그런다.
-- LOCK_MODE가 X 는 쓰기락이 잡혀있다라는 뜻이다.
-- INDEX_NAME에 어디에 잡혀있는지 출력된다.
-- LOCL_DATE는 Index의 값
select *
FROM performance_schema.data_locks
where LOCK_TYPE = 'RECORD';
-- 트랜잭션이 상태 확인
select *
from information_schema.innodb_trx;
트랜잭션2
-- 트랜잭션 2
START TRANSACTION;
SELECT *
FROM POST p
WHERE p.memberId = 2
and p.contents = 'v'
for update;
COMMIT;
추가로 공부 해볼만한 것들!!!
- Java에서의 동시성 이슈 제어 방법
- 분산환경에서의 동시성 이슈제어 방법
- MySQL의 넥스트 키락이 등장한 배경
- MySQL 외래키로 인한 잠금
- MySQL 데드락
728x90
'Server' 카테고리의 다른 글
동시성 제어 (0) | 2024.02.18 |
---|---|
[낙관적락/Optimistic Lock]_기본 개념 (비관적 락/PESSIMISTIC 짧은 설명 포함) (0) | 2024.02.15 |
[비관적인락/PESSIMISTIC]_쓰기락과 읽기락 (0) | 2024.02.06 |
[디자인 패턴] 추상 팩토리 패턴 (0) | 2024.02.03 |
CAP 이론 (0) | 2024.02.03 |