-
Notifications
You must be signed in to change notification settings - Fork 0
Description
05 트랜잭션과 잠금
5.1 트랜잭션
- 논리적인 작업 셋이 100% 적용되거나 아무것도 적용되지 않아야 함을 보장
- COMMIT
- ROLLBACK
- 트랜잭션이 없다면, 여러 동작을 수행했을 때, 중간 작업이 실패 했을 경우 손수 롤백 해야하는 불편함이 있다.
5.1.1 MySQL에서의 트랜잭션
5.1.2 주의사항
- 트랜잭션의 범위는 최소화해야 한다.
- 모놀리식 서비스는 트랜잭션을 하나로 관리가 가능하지만, MSA 는 하나의 트랜잭션으로 묶기 어렵다.
- SAGA 패턴: MSA 에서의 트랜잭션을 SAGA 라는 단위로 묶는다?
5.2 MySQL 엔진의 잠금
- 읽기 잠금
- 쓰기 잠금
5.2.1 글로벌 락
- 서버 전체
- 백업 락
- MySQL 8.0에서는 데이터 변경을 허용하는 백업 락 추가됨
- 테이블 정보 수정 허용 x
5.2.2 테이블 락
- 명시적 락
- 묵시적 락
5.2.3 네임드 락
- 임의의 문자열에 대한 잠금 설정
- 동일 데이터를 변경하거나 참조하는 프로그램끼리 분류하여 네임드 락을 걸고 쿼리 실행
- MySQL 8.0 부터는 네임드 락을 중첩 사용 가능
- 락에다가 이름 같은 것을 설정
- 데드락
- DOG CAT
- CAT DOG
- https://helloworld.kurly.com/blog/vsms-performance-experiment/#%EB%8D%B0%EB%93%9C%EB%9D%BD%EC%9D%98-%EC%9B%90%EC%9D%B8-%EF%B8%8F
5.2.4 메타데이터 락
- 데이터베이스 객체의 이름이나 구조 변경 시 획득하는 잠금
5.3 InnoDB 스토리지 엔진 잠금
- 레코드 기반 잠금
- 최근 버전에서는 트랜잭션 상태와 잠금에 대해서 조회할 수 있는 여러 모니터링 방법 추가
5.3.1 InnoDB 스토리지 엔진의 잠금
- 레코드 락
- 갭(GAP) 락
- 넥스트 키 락
- 자동 증가 락
- https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-gap-locks
5.3.1.1 레코드 락
- 레코드 자체만을 잠금
- MySQL은 인덱스의 레코드를 잠금
- 보조 인덱스의 경우 넥스트 키 락 / 갭 락
- PK 또는 유니크 인덱스의 경우 레코드 락
5.3.1.2 갭 락
- 레코드와 바로 인접한 레코드 사이의 간격만을 잠금
5.3.1.3 넥스트 키 락
- STATEMENT 포맷의 바이너리 로그를 사용하는 경우 REPEATABLE READ 격리 수준 사용해야 함
- 바이너리 로그에 기록되는 쿼리가 레플리카 서버에서 실행될 때 소스 서버에서 만들어 낸 결과와 동일한 결과를 만들어내도록 보장하는 것이 주 목적
- 가능하면 바이너리 로그 포맷을 ROW 형태로 바꾸기
- MySQL 8.0 에서는 기본 설정
- PK Clustered Index 는 Sparse Index 로 구성 가능하고
- Secondary Index 는 dense index 로 구성가능하다.
- 레플리카 서버와 소스 서버에서 만든 쿼리결과가 동일하도록 보장
- 팬텀 리드 문제를 해결하기 위해서 넥스트 키 락이 필요
- 레코드 락과 갭락을 둘다 활용해서 구현된 개념이 넥스트 키 락
5.3.1.4 자동 증가 락
- AUTO_INCREMENT 에 대한 락
- INSERT, REPLACE
5.3.2 인덱스와 잠금
- 인덱스를 사용하면서 접근한 레코드 모두를 잠금
- 그러므로 인덱스 설계가 중요
5.3.3 레코드 수준의 잠금 확인 및 해제
- 잠금 / 트랜잭션 정보에 대한 조회
5.4 MySQL의 격리 수준
- DIRTY READ
- NON-REPEATABLE READ
- PHANTOM READ
5.4.1 READ UNCOMMITTED
- DIRTY READ
- NON-REPEATABLE READ
- PHANTOM READ
5.4.2 READ COMMITTED
- NON-REPEATABLE READ
- PHANTOM READ
5.4.3 REPEATABLE READ
- PHANTOM READ
범위 조회 다른 트랜잭션
id 110 -> 1, 4, 4, 9 insert 7 OK10 -> 1, 4, 4, 7, 9 PHAMTOM READ
id 1
- PHANTOM READ
- JPA는 캐시 구조가 있어 REPEATABLE READ를 기본적으로 지원
5.4.4 SERIALIZABLE
쿼리 테스트용
CREATE TABLE test(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
codesquad BIGINT NOT NULL,
);
INSERT INTO test (codesquad) VALUES (1), (3), (5), (7), (10);
START TRANSACTION;
SELECT * FROM test WHERE id >= 7;
COMMIT;
START TRANSACTION;
EXPLAIN SELECT * FROM test WHERE id = 1 FOR UPDATE;
COMMIT;기타
텍스트
1, 2, 3, 4, 5, ... 10000
인덱스 -> 찾을수 있는거에 대해서, 데이터 페이지 주소를 매핑
id 데이터 페이지 번호 (페이지 주소)
1 -> 1
2 -> 1
3 -> 1
4
5
6
..
1000 -> 1
1001 -> 2
...
1400 -> 2
...
2000 -> 2
10000
-> dense index
index (first_name, last_name)
first_name, record id
GERGI 10001
GERGI 10002
GERGI 10003
GERGI 10007
GERGI 10004
GERGI 10006
GERGY
SELECT 언제든 가능
SELECT FOR SHARE
SELECT FOR UPDATE
UPDATE WHERE first_name = GERGI AND last_name=Klassen
1 -> 1
1001 -> 2
2001 -> 3
-> sparse index
pk clustered index <-
secondary index -> dense index
페이지 1
1,
2
3
4
..
1000
페이지 2
1001
1002
...
2000

