Skip to content

SnackgameBiz 게임 재개/ 종료 시 PessimisticLockingFailureException이 발생하는 문제 #230

@Hwanvely

Description

@Hwanvely

비관적 lock 동시성 문제

Image

며칠 전부터 prod 서버에서 PessimisticLockingFailureException이 비정상적으로 자주 발생하고 있습니다. 😭
그리고 Vingle을 위한 SnackgameBiz에서만 발생한다는 것을 확인하였습니다.. (본체 스낵게임에는 안터지는 것을 봐서 데이터가 많이 쌓인듯..?)

동시성 문제 발생 원인

모든 에러가 end()resume() 둘 중 하나의 경우에 발생하는 것을 보아 둘 다 하나의 game session에 대해 update를 하는 과정에서 lock 충돌이 일어난다고 판단하고 있습니다.

상황 악화 추측 😈

에러의 직접적인 원인은 game session에 대한 lock이지만 이 충돌 확률을 증가시키는 원인들을 추측해보았습니다.

  1. end()에서 resume() 직접 호출
    fun end() {
        validateNotExpired()
        if (pausedAt != null) {
            resume()
        }
        expiresAt = now().minusNanos(1)
    }

한 트랜잭션 내에서 불필요하게 row가 두 번 update 될 수 있는 가능성이 있습니다.

  1. 트랜잭션의 너무 넓은 범위
    현재 end()는 DB 조회 -> 도메인 변경 -> 이벤트 발행 -> 응답 객체 생성
    이 모든 과정을 한 트랜잭션내에 처리하고 있습니다. 이는 lock을 오래 잡고 있어서 충돌 확률을 증가 시킬 수 있습니다.

  2. 인덱스의 부재
    현재 snackgamebiz에는 인덱스가 존재하지 않습니다.

Image

따라서 위와 같이 Full scan이 일어나고 매우 긴 시간이 소요됩니다.

  1. 제대로 작동하지 않는 일시정지 및 재개
    현재 스낵게임은 앱을 Background로 이동 시 실제로 pause 처리가 되지 않아 게임 종료시에 세션 만료가 되어버립니다.
    이 또한 end() resume()의 충돌을 야기할 수 있습니다.

해결 방안 👼🏻

  • end() 내에서 resume() 호출 대신 직접 상태 변경
  • DB 작업과 이벤트 발행 및 응답 객체 생성 분리
  • Indexing
  • Session state 리팩터링
  • CQRS패턴 , Message Queue를 이용한 비동기 이벤트 처리

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingurgentsomething that is urgent and in high-proiority

Type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions