트랜잭셔널 아웃박스 패턴
DB와 외부 시스템 사이의 Dual Write 문제 해결하기
서비스에서 DB를 변경하는 동시에 외부 API 를 호출할 때
게시글 작성 -> 게시글 DB 작성 -> 팔로워에게 알림 발송
CASE1
하나의 트랜잭션으로 묶기
행성이 서버 -> 알림 시스템 트랜잭션 시작 게시글 저장 알림 요청 발송 요청받음 지연발생 알림 메시지 발송 처리 완료 응답 커밋
알림 시스템 외부 시스템 응답 지연 -> 트랜잭션 장기 유지 -> lock connection 점유
CASE2
트랜잭션 분리 게시글 저장 후 알림 시스템 호출 행성이 서버 알림 시스템 트랜잭션 시작 게시글 저장 커밋 알림 발송 요청 (서버 장애나면 알림 발송자체가 수행이 안 됨) 게시글은 저장이 되었지만 (불일치 발생)
CASE3
알림을 보낸 후 게시글 저장 행성이 서버 알림시스템 알림 발송 요청 요청받음 알림 메시지 발송 처리완료응답 트랜잭션시작 게시글 저장 서버 장애나면 롤백되어서 알림은 갔지만, 처리가 안 됐음
DUAL WRITE 문제
두 시스템 중 하나만 성공할 수 있따. 하나의 로컬 트랜잭션으로 원자적으로 처리할 수 없다.
Trnasactional Outbox Pattern
같은 DB 트랜잭션에 저장하고 별도 프로세스가 이를 외부 시스템으로 전달하는 패턴 유실을 방지해주는 역할을 함.
예시
게시글 작성 -> post 테이블, outbox테이블에 저장 (동일 트랜잭션)
워커가 아웃박스 조회 -> 외부 시스템에 전달 -> 알림 발송
조회하는 방식
Polling
일정 주기로 하는 것
- 구현 단순
- 인프라 적음
- 처리 지연 가능
- 반복적 DB 조회
CDC
DB 변경 로그를 읽어 otubox 생성 감지
- 운영 복잡도 증가
- 실시간 처리
WORKER의 역할
- 미처리 outbox 조회
- 외부 시스템 전달 (외부 트랜잭션)
- 성공하면 완료 (내부 트랜잭션)
- 실패하면 재시도
만약 워커가 장애나도 oubox 테이블에 남아있어서 다음 실행 때 하면 됨
outbox에도 남는 문제
전송 성공했지만 워커에 오류가 나면?
oubox 조회 미처리 알람 반환 워커가 알림 시스템에 요청 시스템이 알림 발성 발송 성공 응답반환 알림 100 완료 처리 (여기서 완료가 안 되면 oubox에서 다시 조회해서 동일한 알림 전송)
at least once 는 보장, but exactly once는 보장하지 않음.
Transactional Inbox Pattern
수신한 이벤트와 식별자를 DB ㅡㅌ랜잭션에 저장해서 동일 이벤트를 처리하는 방법 별도의 트랜잭션이었으니, 각각 별도로 처리할 수 있게
미처리 outbox 조회 알림 100 서버로 알림 요청 알림 100 저장 알림 발송 발송 성공 알림 완료처리 실패 알림 조회 알림 요청 알림 100 저장 시도 Inobx. table ( -> unique라서 이미 알림있는거라 알림 재전송을 막아줌.)
멱등성을 확보해서 처리를 해줄 수 있다.