Mysql 데드락 패턴
데드락 발생 패턴
잠금의 종류
- 배타적 잠금
- Exclusive-Lock, Write Lock, X-Lock
- 해당 트랜잭션이 특정 레코드나 간격을 변경하기 위해 획득해야 하는 잠금
- 내가 쓰기를 하는 동안 남들이 쓰지 못하게 하는 것!
- 공유 잠금
- Shared-Lock, Read-Lock, S-Lock
- 레코드나 간격을 읽을 때 다른 트랜잭션이 변경하지 못하게 하는 용도의 잠금
- 내가 읽는 동안 남들이 내가 읽고 있는 데이터를 변경하거나 삭제하지 못하게 막는 장치
프라이머리 키나 유니크 키가 존재하는 테이블에서 INSERT를 수행할 때 공유 잠금을 걸어야하는 이유? INSERT를 전제로 한 읽기 작업 중에 다른 트랜잭션에서 레코드를 변경하거나 삭제하면 일관성이 깨지기 때문 (이전 데이터로 돌아간다던지..)
패턴1 (상호 거래 관련)
- 가장 많이 알려진 데드락 패턴
- A 사용자가 B사용자에게 10포인트를 전달하고, 그와 동시에 B사용자도 A사용자에게 10포인트를 전달 하는 시나리오
| 트랜잭션1 | 트랜잭션2 |
|---|---|
| BEGIN; | |
| BEGIN; | |
| UPDATE tb_user SET point_balance = point_balance - 10 WHERE user_id=‘A’; |
|
| UPDATE tb_user SET point_balance = point_balance - 10 WHERE user_id=‘B’; |
|
| UPDATE tb_user SET point_balance = point_balance + 10 WHERE user_id=‘B’; |
|
| UPDATE tb_user SET point_balance = point_balance + 10 WHERE user_id=‘A’; |
|
| – 데드락 발생 지점– | |
| COMMIT; | |
| COMMIT; |
트랜잭션 1번에서 A 대해 배타적 잠금을 가지고 있고, 동시에 트랜잭션 2번은 B에 대해 배타적 잠금을 가지고 있음 이 상태에서 다시 각자 상대방 트랜잭션에서 가지고 있는 레코드를 변경하기 위해 배타적 잠금을 요청하면 데드락이 발생함
패턴2 (유니크 인덱스 관련)
- 공유 잠금과 배타적 잠금이 혼합된 형태