Skip to content

뺀 토너먼트 후보를 다시 담을 때 나는 500 해소 #1246

Description

@sevineleven

왜

뺀 후보를 다시 담으면 500

  • prod 24시간 ERROR 19건이 전부 이 오류
  • 디스코드 알림 3건은 그 19건이 시간대별로 묶여 나간 것
  • 사용자 조작은 정상
    • 담기·빼기 각각 200
  • 원인: 빼기가 행을 지우지 않고 deleted_at 만 채움
    • 담기의 중복 검사는 살아 있는 행만 봄(findAllByTournamentIdAndNotDeleted)
    • 유니크 키 uk_tournament_items (tournament_id, snapshot_id) 는 삭제 표시된 행까지 셈
    • 위시가 가리키는 snapshot 이 그대로라 같은 조합으로 insert
  • 결과: DataIntegrityViolationException 이 전용 처리기 없이 handleUnexpected 까지 내려가 500 과 ERROR 로그
  • 재현: 담기 → 빼기 → 재담기 통합 테스트에서 Duplicate entry '1-1' for key 'tournament_items.uk_tournament_items' 확인

플레이 기록 참조는 없음

  • 담기·빼기 둘 다 isPending() 전용
    • 결과: 삭제행을 가리키는 tournament_histories 가 생길 수 없음

무엇을

유니크 키를 활성 행 한정으로 전환

  • generated 컬럼으로 삭제행을 유일성 판정에서 제외
    • 참조: uk_tournaments_active_invite_code 선례
    • 원인: MySQL 이 partial unique index 를 지원하지 않음
  • 결과: 재담기가 새 행 insert 로 정상 성공
  • 조회 인덱스는 그대로
    • 원인: 새 키의 선행 컬럼이 tournament_id 로 같음
선택지 재담기 후 대기실 순서 담은 사람 갱신 마이그레이션
활성 행 한정 유니크 (채택) 맨 뒤 불필요 필요
삭제행 되살리기 원래 자리로 복귀 필요 없음
  • 기각: 되살린 행은 옛 id·생성시각을 유지해 ORDER BY id ASC 에서 재담은 후보가 원래 자리로 돌아감

회귀 가드

  • 담기 → 빼기 → 재담기 통합 테스트

범위

  • 예외 처리기 추가 없음
    • 원인: 고치면 재담기가 정상 성공
    • 진짜 중복(이미 활성인 후보 담기)은 지금도 409 duplicateTournamentItem 으로 걸림

Activity

  1. self-assigned this
    on Oct 21, 2026
  2. added theissue type on Oct 21, 2026
  3. added a commit that references this issue on Oct 21, 2026
    eb17a87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

fix외부 가시적 결함 수정

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions