jayeon@portfolio — jsh — 92×34
jayeon@portfolio~/projects%cat projects/bbgg.md
위치 쿼리 성능 — Bounding Box + ST_Distance_Sphere 2단계 필터링
문제: jOOQ OSS에서 stDistance 함수 미지원. 대규모 위치 데이터에서 정밀 거리 필터링을 라이선스 추가 없이 구현해야 함.
설계: Bounding Box로 1차 후보군을 (위도·경도) 복합 인덱스로 빠르게 축소한 후, ST_Distance_Sphere로 2차 정밀 필터링. jOOQ DSL에서 네이티브 SQL 함수로 직접 호출.
효과: 엔터프라이즈 라이선스 없이 대규모 위치 쿼리 성능 확보. 복합 인덱스 활용으로 전체 테이블 스캔 회피.
순례 코스 — 상태 머신 + 멱등 체크인 + 공유 초대
문제: 코스 계획·실행·기록·공유에서 중복 체크인·중복 기록·재시도 안전성이 필요.
설계: 코스 상태 머신(계획→진행→완료)으로 진행을 관리. 체크인은 (코스·빵집·사용자) 중복 조회로 멱등 처리해 완주 시 여정 기록을 1회만 생성. 공유는 링크/닉네임 초대 + 1회 사용 토큰.
효과: 클라이언트 재시도에도 중복 기록·중복 달성이 없고, 코스 진행·공유가 안전하게 동작.
공공데이터 동기화 — 청크 단위 REQUIRES_NEW 트랜잭션 격리 (협업)
문제: 팀의 공공데이터 대량 동기화에서 일부 행 실패 시 전체 롤백, 긴 트랜잭션으로 락 경합 위험.
설계: 팀 동기화 로직에 청크 단위 @Transactional(REQUIRES_NEW) 트랜잭션 경계를 도입해 청크별 독립 커밋. 실패 행은 실패 이력 테이블에 남겨 부분 실패 허용, 락 보유 시간 단축.
효과: 한 청크 실패가 전체 동기화를 막지 않음. 실패 행 재처리 가능. 락 경합 감소로 동기화 중 서비스 응답 영향 최소화.
```mermaid
graph TD
  A[위치 검색 요청 lat/lng/radius] --> B[1단계: Bounding Box 필터]
  B -->|위도·경도 복합 인덱스| C[후보군 축소]
  C --> D[2단계: ST_Distance_Sphere 정밀 필터]
  D --> E[최종 결과 반환]
  style B fill:#f4f4f5
  style D fill:#f4f4f5
```
Bounding Box + ST_Distance_Sphere 2단계 위치 쿼리
```mermaid
graph TD
  A[공공데이터 동기화 배치] --> B{청크 분할}
  B --> C[청크 1]
  B --> D[청크 2]
  B --> E[청크 N]
  C -->|REQUIRES_NEW 트랜잭션| F{처리 결과}
  D -->|REQUIRES_NEW 트랜잭션| F
  E -->|REQUIRES_NEW 트랜잭션| F
  F -->|성공| G[커밋]
  F -->|실패| H[실패 이력 테이블 기록]
  H --> I[다음 청크 계속 진행]
```
청크 단위 REQUIRES_NEW 격리 + 실패 이력 구조
# 관련 링크
2026.01 — 2026.03 · 될랩

빵빵곡곡 (BbggApi)

"전국 방방곡곡, 빵빵곡곡" — 위치 기반 빵집 발견과 순례 코스 계획·실행·기록·공유 앱의 백엔드 API 서버.

Java 21jOOQMySQLWebClientTestContainers

위치 쿼리 성능 — Bounding Box + ST_Distance_Sphere 2단계 필터링

문제
jOOQ OSS에서 stDistance 함수 미지원. 대규모 위치 데이터에서 정밀 거리 필터링을 라이선스 추가 없이 구현해야 함.
설계
Bounding Box로 1차 후보군을 (위도·경도) 복합 인덱스로 빠르게 축소한 후, ST_Distance_Sphere로 2차 정밀 필터링. jOOQ DSL에서 네이티브 SQL 함수로 직접 호출.
효과
엔터프라이즈 라이선스 없이 대규모 위치 쿼리 성능 확보. 복합 인덱스 활용으로 전체 테이블 스캔 회피.

순례 코스 — 상태 머신 + 멱등 체크인 + 공유 초대

문제
코스 계획·실행·기록·공유에서 중복 체크인·중복 기록·재시도 안전성이 필요.
설계
코스 상태 머신(계획→진행→완료)으로 진행을 관리. 체크인은 (코스·빵집·사용자) 중복 조회로 멱등 처리해 완주 시 여정 기록을 1회만 생성. 공유는 링크/닉네임 초대 + 1회 사용 토큰.
효과
클라이언트 재시도에도 중복 기록·중복 달성이 없고, 코스 진행·공유가 안전하게 동작.

공공데이터 동기화 — 청크 단위 REQUIRES_NEW 트랜잭션 격리 (협업)

문제
팀의 공공데이터 대량 동기화에서 일부 행 실패 시 전체 롤백, 긴 트랜잭션으로 락 경합 위험.
설계
팀 동기화 로직에 청크 단위 @Transactional(REQUIRES_NEW) 트랜잭션 경계를 도입해 청크별 독립 커밋. 실패 행은 실패 이력 테이블에 남겨 부분 실패 허용, 락 보유 시간 단축.
효과
한 청크 실패가 전체 동기화를 막지 않음. 실패 행 재처리 가능. 락 경합 감소로 동기화 중 서비스 응답 영향 최소화.
Bounding Box + ST_Distance_Sphere 2단계 위치 쿼리
청크 단위 REQUIRES_NEW 격리 + 실패 이력 구조