Last updated
Last updated
마켓보로에서 일하면서 생긴 트랜잭션 문제에 대해 시니어님과 교류한 내용입니다.
이 글은 블로그로 이관되었습니다.
Table단위의 LOCK
이 걸리는가? 아니면 ROW단위의 LOCK
이 걸리는가? (레코드 락)
ROW단위
: 특정 데이터에만 SHARED LOCK
이 걸리고, 다른데이터의 CRUD
에는 영향이 없는가?
SHARED LOCK
: 읽기 가능. 수정/삭제 불가
Transaction Mode: Manual
col1=1
S락 획득 시도
primaryKey=1
S락 획득 성공
col1=2
X락 획득 시도
primaryKey=2
X락 획득 성공
col1=1
X락 획득 시도
하지만 Session 1 에서 S락을 걸고 있기에 호환되지 않아 WAITING.
락이 걸리지 않은 레코드에는 update가 가능하다.
S락이 걸린 레코드에 X락이 들어오면 S락이 해제될 때까지 기다린다.
S락과 X락은 호환되지 않는다.
timeout의 주범.
즉 InnoDB는 레코드락으로 움직인다.
정리하면서 최근 읽은 REAL MySQL의 잠금 파트가 생각나서 다시 읽어봤습니다.
이 내용을 읽고 앞의 테스트를 다시 보니
where 조건의 col1은 PK이기에 unique index로 이미 잡혀있어 단일 레코드락이 걸립니다.
하지만 index가 없는 col2라면?
col2에 non unique index를 걸고 조회한다면?
index가 아닌 col2를 where 조건으로 실행하는 경우 레코드락이 어떻게 잡히는가?
초기 세팅 동
col2=bbb
S락 획득 시도.
하지만 모든 레코드에 대해 S락 획득 성공.
col2=ccc
X락 획득 시도.
하지만 Session 1 에서 모든 레코드에 S락을 걸고 있기에 호환되지 않아 WAITING.
index가 없다면 모든 레코드가 락에 걸린다.
col2에 non unique index를 걸고 where 조건으로 실행하는 경우 레코드락이 어떻게 잡히는가?
col2=bbb
S락 획득 시도
primaryKey=3,4,5
S락 획득 성공
col2는 non unique index 이지만 primaryKey=3,4
S락 획득 성공.
primaryKey=5
도 S락이자 GAP락으로 획득했는데 이부분은 좀 더 공부해야됩니다.
col2=ccc
X락 획득 시도
primaryKey=5,6
X락 획득 성공
근데 unique index이던 것과 다르게 REC_NOT_GAP, GAP 락들이 추가로 획득됩니다.
col2=bbb
X락 획득 시도
하지만 Session 1 에서 S락을 걸고 있기에 호환되지 않아 WAITING.
테스트 1과 결과는 같지만 락이 걸리는 형태가 매우 다릅니다.
INSERT INTO SELECT SHARED LOCK
는 레코드 락이 맞습니다.하지만 non unique index의 경우 락이 걸리는 형태가 매우 다릅니다.
IS, IX, 갭 락등에 대한 공부가 부족해 정확히 어떤 차이가 있는지 잘 모르겠습니다.
심지어 no index 인 경우는 전체 레코드 락으로 테이블 락과 같은 상태가 됩니다.
이 이슈는 일반적이지 않은 업무 흐름에서 수기 작업 간 트랜잭션 조작을 잘못한 인적 실수가 더 큽니다. (영업의 요청)
실무에서 사용되는 테이블은 최소한 non unique index가 걸려 있을 것입니다.