핵심 비교 느린 외부 호출은 트랜잭션 밖에서 끝내고, DB에는 성공 결과만 짧게 기록합니다.

같은 결제 흐름이라도 트랜잭션 경계를 어디에 두느냐에 따라 잠금 시간, 동시성, 실패 처리 범위가 크게 달라집니다.

공통 목표

결제 성공이 확인되면 orders.status = 'PAID'INSERT INTO payment_log 를 같은 커밋으로 남겨 상태와 로그를 함께 맞춥니다.

비교 축
잘못된 경계
권장 경계
잠금 구간
잠금이 길게 유지
주문 UPDATE 후 바로 시작 외부 API 5초 대기까지 포함
기록 순간만 잠금
결제 성공 확인 후 BEGIN 상태 변경과 로그 기록 뒤 즉시 커밋
시작 시점
UPDATE orders ... 를 먼저 실행한 뒤 외부 호출을 기다립니다.

DB 상태를 건드린 시점부터 트랜잭션이 열려 있으므로, 외부 응답이 늦어질수록 잠금도 함께 늘어납니다.

외부 결제 성공을 확인한 다음에만 짧은 트랜잭션을 엽니다.

네트워크 지연은 트랜잭션 밖에서 소화하고, DB에는 확정된 결과만 반영합니다.

DB 기록 방식
상태를 먼저 바꿔 둔 채 나머지 결과를 기다리는 구조입니다.

외부 호출 실패 시 롤백 범위가 커지고, 처리 도중 다른 세션이 오래 대기할 수 있습니다.

orders 상태 변경과 payment_log 기록을 한 번에 묶습니다.

DB 안에서는 일관된 성공 결과만 남기므로, 커밋 이후 상태가 더 예측 가능해집니다.

운영 결과
잠금 대기와 동시성 저하가 외부 API 품질에 직접 끌려갑니다.

애플리케이션 바깥의 느린 응답이 DB 병목으로 번지는 전형적인 패턴입니다.

트랜잭션 지속 시간이 짧아져 성능과 정합성을 함께 지키기 쉽습니다.

실패는 트랜잭션 밖에서 재시도하고, DB 안에서는 확정된 상태만 빠르게 저장하면 됩니다.

정리: 외부 시스템과 엮인 작업에서는 "느린 대기"와 "DB 커밋" 을 같은 경계에 넣지 않는 것이 핵심입니다.