728x90
Deadlock Error 처리
에러 발생
위와 같이 DeadLock 이 나는 경우가 종종 잦아지는데 이유는 위와 같이 동일 요청이 두번오게 되는데 이 시점에 데드락걸릴 확률이 상당히 높습니다.
일단 간단히 데드락이 나는 이유를 위해서 코드를 봐야하는데 코드는 대략적으로 아래와 같은 구조입니다.
문제
- 해당 푸시 토큰과 같은 로우면를 업데이트 하고, 아니면 INSERT 해라 (INSERT... ON DUPLICATE KEY UPDATE)
- 해당 푸시 토큰과 유저 아이디가 같은 로우를 찾는 쿼리
- 푸시 토큰을 넘겨받았으면 nil 로 바꿔라 (어플리케이션 로직)
- 같은 푸시 토큰을 가지고 있는 로우가 있는데 유저가 다르다면 있다면 그건 nil 로 바꿔버려라
즉 위의 코드를 봤을때 중복 요청이 들어오면 충분히 데드락을 발생시킬 수 있습니다. 아래 그림과 같은 상황이 오게될테니 말이죠
이런 상황이 펼쳐질 수 있습니다.
즉 3번 쿼리는 하나의 트랜잭션에서 배치성으로 이루어지는 쿼리이므로 한 트랜잭션이 여러 row 에 대한 쓰기 잠금을 풀었다 잠궜다가 할 수 있게 됩니다. 그래서 중복요청이 들어오게 되면 데드락이 걸릴 확률이 증가하게 됩니다.
해결 방안
중복 요청을 제거하자.
이 쿼리는 중복으로 일어나면 일어날 수록 데드락 확률이 증가한다.
음 따라서 메소드 안에서 중복 요청을 막아야 할까? 하지만 이 메소드를 쓰는 곳이 항상 중복 체크를 필요로 할까는 의문이다.
따라서 메소드 자체는 단순히 쿼리를 작업하는 일을 하고, 중복 처리 요청은 다른 곳에서 해야할 것 같았다.
지금 발생하는 이유를 로그를 찾아올라가 보니 유저 로그인에서 발생하고 있었다.
같은 시간대 History 가 두개를 생긴게 보니 따닥이 분명하다.
로그인 하는 곳에서 Redis 를 만료시간을 이용해서 duplicate 를 처리했다.
728x90
'데이터베이스 > MySQL' 카테고리의 다른 글
인덱스 스캔 방식 (0) | 2021.11.08 |
---|---|
MySQL Index (0) | 2021.10.31 |
MySQL Lock System (0) | 2021.10.25 |
MySQL 에 쿼리가 들어왔을때? (0) | 2021.10.21 |
InnoDB 엔진의 특성 (2) | 2021.10.12 |