프로듀서 → 컨슈밍 아웃박스 상황에서 해당 메서드가 핵심 비즈니스 로직을 전부 수행하고 리턴할 때 에러 발생
@KafkaListener(
topics = {Topic.INCREASE_STOCK_EVENT},
groupId = "on-ssgdeal-group-increase-stock",
containerFactory = "kafkaListenerContainerFactory"
)
public void listenIncreaseStockEvent(
@Payload String message,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
Acknowledgment ack
) {
try {
log.info("메시지를 소비합니다. Topic : {}, message :{}", topic, message);
EventEnvelope<IncreaseStockEvent> envelope =
EventEnvelope.fromJson(message, IncreaseStockEvent.class);
IncreaseStockEvent payload = envelope.payload();
productService.increaseStock(payload.toDto());
ack.acknowledge();
} catch (Exception e) {
log.error("메시지 소비에 실패했습니다. => {}", e.getMessage());
throw e;
}
}
핵심 에러 사항
no thread-bound request found: are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? if you are actually operating within a web request and still receive this message, your code is probably running outside of dispatcherservlet: in this case, use requestcontextlistener or requestcontextfilter to expose the current request.
현재 JpaAuditingConfig 상황
→카프카의 전송은 Web이 아니라 httpServletRequest로 해당 요청이 들어오지 않아
UpdateAt을 수행하지 못하고 있었음
@Bean
public AuditorAware<Long> loginUserAuditorAware() {
return () -> {
String requestUri = httpServletRequest.getRequestURI();
String requestMethod = httpServletRequest.getMethod();
if (
isCreateUserRequest(requestUri, requestMethod) ||
isSignupAuthRequest(requestUri, requestMethod) ||
isLoginAuthRequest(requestUri, requestMethod)
) {
return Optional.empty();
}
Passport passport = passportUtil.getPassportBy(httpServletRequest);
return Optional.of(passport.getUserId());
};
}
구분 | MDC | ThreadLocal |
---|---|---|
목적 | 로깅 시 컨텍스트 정보 추적 | 쓰레드별 변수 격리 |
사용 편의성 | 로깅에 최적화된 API 제공 | Low-level API 직접 사용 |
내부 구현 | ThreadLocal 기반 | Java 언어 차원의 기능 |
스레드 풀 위험성 | **MDC.clear() **로 정리 가능 |
수동 정리 필요 (메모리 누수 가능성) |
사용 예시 | 로그에 사용자 ID, 요청 ID 추가 | DB 연결 관리, 보안 컨텍스트 |