-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
bugSomething isn't workingSomething isn't workingurgentsomething that is urgent and in high-proioritysomething that is urgent and in high-proiority
Description
비관적 lock 동시성 문제
며칠 전부터 prod 서버에서 PessimisticLockingFailureException이 비정상적으로 자주 발생하고 있습니다. 😭
그리고 Vingle을 위한 SnackgameBiz에서만 발생한다는 것을 확인하였습니다.. (본체 스낵게임에는 안터지는 것을 봐서 데이터가 많이 쌓인듯..?)
동시성 문제 발생 원인
모든 에러가 end() 와 resume() 둘 중 하나의 경우에 발생하는 것을 보아 둘 다 하나의 game session에 대해 update를 하는 과정에서 lock 충돌이 일어난다고 판단하고 있습니다.
상황 악화 추측 😈
에러의 직접적인 원인은 game session에 대한 lock이지만 이 충돌 확률을 증가시키는 원인들을 추측해보았습니다.
end()에서resume()직접 호출
fun end() {
validateNotExpired()
if (pausedAt != null) {
resume()
}
expiresAt = now().minusNanos(1)
}
한 트랜잭션 내에서 불필요하게 row가 두 번 update 될 수 있는 가능성이 있습니다.
-
트랜잭션의 너무 넓은 범위
현재end()는 DB 조회 -> 도메인 변경 -> 이벤트 발행 -> 응답 객체 생성
이 모든 과정을 한 트랜잭션내에 처리하고 있습니다. 이는lock을 오래 잡고 있어서 충돌 확률을 증가 시킬 수 있습니다. -
인덱스의 부재
현재 snackgamebiz에는 인덱스가 존재하지 않습니다.
따라서 위와 같이 Full scan이 일어나고 매우 긴 시간이 소요됩니다.
- 제대로 작동하지 않는 일시정지 및 재개
현재 스낵게임은 앱을Background로 이동 시 실제로pause처리가 되지 않아 게임 종료시에 세션 만료가 되어버립니다.
이 또한end()와resume()의 충돌을 야기할 수 있습니다.
해결 방안 👼🏻
-
end()내에서resume()호출 대신 직접 상태 변경 - DB 작업과 이벤트 발행 및 응답 객체 생성 분리
- Indexing
-
Session state리팩터링 - CQRS패턴 , Message Queue를 이용한 비동기 이벤트 처리
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingurgentsomething that is urgent and in high-proioritysomething that is urgent and in high-proiority
Type
Projects
Status
No status