Skip to content

Commit 9a5c84f

Browse files
committed
feat: 폴백 시 아웃박스 패턴 적용
1 parent c472a53 commit 9a5c84f

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

apps/commerce-api/src/main/java/com/loopers/infrastructure/kafka/producer/PaymentEventProducer.java

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
package com.loopers.infrastructure.kafka.producer;
22

3+
import com.loopers.domain.outbox.OutboxService;
34
import com.loopers.infrastructure.kafka.dto.PaymentEventDto;
45
import io.github.resilience4j.retry.annotation.Retry;
56
import lombok.RequiredArgsConstructor;
67
import lombok.extern.slf4j.Slf4j;
78
import org.springframework.beans.factory.annotation.Value;
89
import org.springframework.kafka.core.KafkaTemplate;
910
import org.springframework.stereotype.Component;
11+
import org.springframework.transaction.annotation.Propagation;
12+
import org.springframework.transaction.annotation.Transactional;
1013

1114
@Slf4j
1215
@Component
1316
@RequiredArgsConstructor
1417
public class PaymentEventProducer {
1518

1619
private final KafkaTemplate<Object, Object> kafkaTemplate;
20+
private final OutboxService outboxService;
1721

1822
@Value("${kafka.topic.payment-events-name}")
1923
private String paymentEventsTopic;
@@ -39,15 +43,64 @@ public void sendPaymentPendingEvent(Long orderId, Long userId, String transactio
3943
log.info("결제 대기 이벤트 발행: orderId={}, transactionId={}", orderId, transactionId);
4044
}
4145

46+
@Transactional(propagation = Propagation.REQUIRES_NEW)
4247
public void paymentSuccessFallback(Long orderId, Long userId, String transactionId, Long amount, Throwable ex) {
43-
log.error("결제 성공 이벤트 발행 실패: orderId={}", orderId, ex);
48+
log.error("결제 성공 이벤트 발행 실패, Outbox에 저장: orderId={}", orderId, ex);
49+
50+
try {
51+
PaymentEventDto event = PaymentEventDto.success(orderId, userId, transactionId, amount);
52+
53+
outboxService.saveEvent(
54+
"PAYMENT",
55+
orderId.toString(),
56+
"PAYMENT_SUCCESS",
57+
paymentEventsTopic,
58+
orderId.toString(),
59+
event
60+
);
61+
} catch (Exception e) {
62+
log.error("Fallback Outbox 저장 실패: orderId={}", orderId, e);
63+
// 최후의 수단: 별도 실패 테이블에 저장하거나 알림 발송
64+
}
4465
}
4566

67+
@Transactional(propagation = Propagation.REQUIRES_NEW)
4668
public void paymentFailedFallback(Long orderId, Long userId, String failureReason, Throwable ex) {
47-
log.error("결제 실패 이벤트 발행 실패: orderId={}", orderId, ex);
69+
log.error("결제 실패 이벤트 발행 실패, Outbox에 저장: orderId={}", orderId, ex);
70+
71+
try {
72+
PaymentEventDto event = PaymentEventDto.failed(orderId, userId, failureReason);
73+
74+
outboxService.saveEvent(
75+
"PAYMENT",
76+
orderId.toString(),
77+
"PAYMENT_FAILED",
78+
paymentEventsTopic,
79+
orderId.toString(),
80+
event
81+
);
82+
} catch (Exception e) {
83+
log.error("Fallback Outbox 저장 실패: orderId={}", orderId, e);
84+
}
4885
}
4986

87+
@Transactional(propagation = Propagation.REQUIRES_NEW)
5088
public void paymentPendingFallback(Long orderId, Long userId, String transactionId, Throwable ex) {
51-
log.error("결제 대기 이벤트 발행 실패: orderId={}", orderId, ex);
89+
log.error("결제 대기 이벤트 발행 실패, Outbox에 저장: orderId={}", orderId, ex);
90+
91+
try {
92+
PaymentEventDto event = PaymentEventDto.pending(orderId, userId, transactionId);
93+
94+
outboxService.saveEvent(
95+
"PAYMENT",
96+
orderId.toString(),
97+
"PAYMENT_PENDING",
98+
paymentEventsTopic,
99+
orderId.toString(),
100+
event
101+
);
102+
} catch (Exception e) {
103+
log.error("Fallback Outbox 저장 실패: orderId={}", orderId, e);
104+
}
52105
}
53106
}

0 commit comments

Comments
 (0)