외부 제휴 연동이나 주문·취소 배치 작업을 하다 보면 같은 데이터가 여러 번 처리될 가능성을 항상 고려해야 한다. 특히 주문, 취소, 클레임처럼 짧은 시간 안에 많은 요청이 들어오고 상태가 계속 바뀌는 업무에서는 단순히 “대상 데이터를 조회해서 처리한다”는 방식만으로는 안전하지 않다.
예를 들어 취소 대상 데이터를 조회한 뒤 처리하는 도중에 다른 배치나 수동 처리 로직이 같은 데이터를 다시 가져가면, 동일 건에 대해 중복 API 호출이 발생하거나 내부 상태가 두 번 변경될 수 있다. 외부 API 호출은 성공했지만 내부 후처리가 실패하는 경우, 반대로 내부 상태는 변경됐지만 외부 전송 결과를 저장하지 못하는 경우도 생길 수 있다. 그래서 이런 업무에서는 “지금 이 데이터는 누가 처리 중인가?”를 DB 기준으로 명확히 표시하는 과정이 필요하다.
내가 이해한 선점 처리는 처리할 데이터를 가져오기 전에 먼저 작업 상태를 바꾸어 다른 프로세스가 같은 데이터를 가져가지 못하게 하는 방식이다. 예를 들어 처리 대기 상태인 데이터를 조회한 뒤 바로 작업 중 상태로 변경하고, 이후 실제 API 호출과 내부 상태 반영을 진행한다.
UPDATE claim_table
SET process_status = 'PROCESSING',
worker_id = :workerId,
updated_at = NOW()
WHERE claim_id = :claimId
AND process_status = 'READY';
여기서 중요한 점은 WHERE process_status = 'READY' 조건이다. 단순히 claim_id만 보고 업데이트하는 것이 아니라, 아직 처리 대기 상태인 데이터만 작업 중으로 바꾼다. 그리고 업데이트된 row 수가 1건일 때만 내가 선점에 성공한 것으로 보고 다음 처리를 진행한다. 만약 0건이라면 이미 다른 작업이 먼저 가져갔거나 상태가 바뀐 것이므로 더 이상 처리하지 않는다.
이 방식은 동시에 여러 작업이 실행되더라도 같은 건을 중복 처리하지 않도록 막아준다. 특히 배치가 여러 번 실행되거나, 운영자가 수동 재처리를 하거나, 외부 API에서 같은 취소 요청이 다시 수집되는 상황에서 효과적이다. 처리 대상 선점, 처리 이력 저장, 최종 상태 변경을 분리해두면 실패 지점도 더 명확하게 추적할 수 있다.
물론 선점만으로 모든 문제가 해결되는 것은 아니다. 작업 중 상태로 바꾼 뒤 서버가 죽거나 외부 API 호출 중 오류가 발생하면 데이터가 계속 PROCESSING 상태로 남을 수 있다. 그래서 선점 시간, 재처리 가능 여부, 실패 상태 전환 기준도 함께 설계해야 한다. 예를 들어 일정 시간이 지난 PROCESSING 데이터는 별도 재처리 대상으로 분리하거나, 실패 사유를 저장한 뒤 운영자가 확인할 수 있도록 해야 한다.
READY
→ PROCESSING
→ SUCCESS
READY
→ PROCESSING
→ FAILED
→ RETRY_READY
→ PROCESSING
→ SUCCESS
결국 중요한 것은 “한 번만 처리되어야 하는 데이터”와 “실패했을 때 다시 처리되어야 하는 데이터”를 구분하는 것이다. 주문과 취소 업무에서는 같은 요청이 여러 번 들어올 수 있지만, 실제 비즈니스 결과는 한 번만 반영되어야 한다. 그래서 DB 선점 처리는 단순한 상태값 변경이 아니라, 멱등성과 재처리를 가능하게 만드는 운영 기준에 가깝다고 느꼈다.
이번 작업을 하면서 배운 점은 외부 API 연동에서 어려운 부분이 API 호출 자체만은 아니라는 것이다. 더 어려운 부분은 상태가 바뀌는 중간 과정에서 같은 데이터가 중복 처리되지 않게 막고, 실패했을 때 어디서부터 다시 시작할 수 있는지 남겨두는 일이었다. 기능이 정상 케이스에서 한 번 동작하는 것보다, 운영 중 실패와 재처리를 견딜 수 있는 구조를 만드는 것이 훨씬 중요했다.
'spring' 카테고리의 다른 글
| 제휴사 개발을 위한 멱등성 처리는? (0) | 2026.08.30 |
|---|---|
| 파이어베이스, 원링크 전환으로 인한 원클릭 수정 (0) | 2025.11.11 |
| Java Batch Job (0) | 2025.11.10 |
| [ Spring Boot 3 + Spring Security 6 + OAuth2.0 + JWT ] 마이그레이션과 같이 진행되는 OAuth2 로그인/회원가입 3 (0) | 2023.12.22 |
| [ Spring Boot 3 + Spring Security 6 + OAuth2.0 + JWT ] 마이그레이션과 같이 진행되는 OAuth2 로그인/회원가입 2 (1) | 2023.12.22 |