결제 승인과 포인트 적립, 차감을 별도의 트랜잭션으로 분리했다. 포인트 적립, 차감에 실패했다고 해서 결제 관련 로직을 통째로 롤백시키는 건 이상하다고 생각했기 때문이다. @TransactionalEventListener로 코드 분리해서, 이벤트에서 포인트 적립, 차감시키게 했는데. 그런데 회원이 결제에 성공했는데 포인트 적립, 차감이 적용되지 않아도 문제다. 포인트가 정상적인 상태가 아닐 때 회원이 그 포인트로 또 결제에 성공하면 데이터가 상당히 어긋나게 된다.
몇 가지 방법이 있는데:
1. 보상 트랜잭션
포인트 적립, 차감에서 예외 발생 시 보상 트랜잭션을 발행하여 결제를 취소시키는 것이다. 이건 너무 이상한 것 같다. 포인트 적립에 실패했다고 해서 무려 성공했던 결제를 다시 환불하기까지 한다는 점이. 게다가 결제 환불도 안 되면 더 문제다. 외부 서비스 호출하는 거라 내 마음대로 제어도 안 되고.
2. 재시도
한 두번 재시도해서 잘 변경되면 좋긴 한데 만약 서버에 10분 정도 문제가 생기면 어떡함? 그럼 100번 재시도해도 소용이 없다. 10분동안 이것만 재시도하느라 다른 API 처리할 리소스를 계속 붙잡아놓을 수도 없고.
3. 알림 + 수동 적립, 차감
비정상적인 상태 발생 시 관리자에게 알림이 가게 하고, 관리자가 민첩하게 수동으로 사후 적립, 차감을 시킬 수 있도록 관리자용 API를 만드는 것이다.
4. 배치
주기적으로 포인트 적립, 차감이 안 된 결제 데이터를 찾아서 불일치를 해결하는 배치를 돌리는 것이다. 좀 과한 것 같기도 하고. 실무에서도 이렇게 하는지는 모르겠다.
5. 2, 3, 4번 혼합
재시도도 3번 정도 하고, 재시도해도 실패하면 알림가게 하고, 수동 사후 적립 API도 만들고, 배치도 돌리면 안전하지 않을까?
'낙서 > 고민' 카테고리의 다른 글
| 사이드 프로젝트하면서 한 고민 여러가지 (0) | 2024.06.24 |
|---|