1. 문제
결제는 성공했는데 매칭은 안 잡히는 등의 ‘시스템 간 불일치’가 발생할 수 있습니다.
현대 서비스는 여러 개의 시스템이 쪼개져 작동합니다. 만약 매칭 시스템에서 작업이 끝났는데 상대방에게 알림을 보내는 시스템이 일시적으로 고장 나면, 사용자는 돈만 내고 서비스를 받지 못하는 심각한 오류를 겪게 됩니다.
2. 왜 필요한가
하나의 작업은 모든 연관 시스템에서 동시에 성공하거나 동시에 취소되어야 합니다.
사용자의 액션 하나는 데이터베이스 저장, 결제, 푸시 알림 등 수많은 연쇄 작업을 일으킵니다. 이 중 하나라도 누락되면 데이터가 꼬이게 되고, 이는 곧 고객의 직접적인 금전적 피해나 강력한 항의로 이어지게 됩니다. 완벽한 정합성 보장이 필수입니다.
3. 기대효과
어떤 시스템 장애 앞에서도 고객 데이터와 결제 내역이 꼬이는 일이 완전히 사라집니다.
서버가 갑자기 다운되거나 네트워크가 끊겨도 데이터는 절대 유실되지 않습니다. 시스템이 복구되면 멈췄던 지점부터 다시 안전하게 작업을 재개하여 고객에게 100% 신뢰할 수 있는 안정적인 서비스를 제공합니다.
4. 구현 방향
중요한 메시지를 ‘반드시 배달되는 안전 우체통’에 먼저 보관한 뒤 처리합니다.
핵심 데이터를 저장할 때, 외부로 보낼 알림이나 이벤트 메시지도 함께 같은 데이터베이스의 임시 보관함(Outbox)에 묶어 저장합니다. 이후 별도의 배달 시스템이 보관함의 메시지를 꺼내어 외부 시스템에 끈질기게 재전송하여 전송 성공을 100% 보장합니다.
@Transactional
public void createMatch(Long user1, Long user2) {
// 1. 매칭 데이터베이스 저장
matchRepository.save(new Match(user1, user2));
// 2. 알림용 이벤트 아웃박스(Outbox) 저장
outboxRepository.save(new OutboxEvent("MATCH_CREATED", user1, user2));
}
5. 비즈니스 가치
크리티컬한 데이터 오류를 원천 차단하여 기업의 금전적, 평판적 리스크를 제거합니다.
수십만 건의 매칭과 결제가 일어나는 대규모 시스템에서도 치명적인 정합성 오류가 발생하지 않습니다. 이는 시스템 복구에 들어가는 막대한 운영 비용을 절감시키며, 고객에게 금융권 수준의 탄탄한 신뢰를 제공하게 됩니다.