본문 바로가기
회고 모음/Project

웹소설 서비스 만들기-3

by e-pd 2023. 4. 17.

사진: Unsplash 의 Renate Vanaga

결제

  • 결제. 쉽지 않다. 무난하게 생각하면 필요한 상품정보 받고, 돈을 지불하면 끝이지만, 갑자기 여러명이 동시에 요청을 했다면?!
    한번만 어떻게 결제를 처리할 수 있을까?
    우선 생각나는 아이템은 메시지큐, 레디스 정도이다. 레디스를 사용하면 동시성 제어의 장점을 살리면서 처리할 수 있다. 싱글 스레드로 작동해서 결제하기전 정보와 요청정보를 비교함으로서 중복결제를 피할 수 있을 것 같다. 하지만 지금은 레디스는 사용하지않고 해결해보기로 했다. 비용적인 측면에서 메시지큐도 제외.

  • 결국은 동시에 못가져가게 막아야한다. 대체 결제에 무엇을 못가져가게 막아야할까? 재고처럼 키를 두고, 사용했는지 안했는지 확인하면 되지 않을까? 발급키를 주고 사용했는지 안했는지 여부로 중복을 막아보기로 했다.

일부 개념은 카카오페이 기술 블로그를 참고했습니다. 글을 읽다보면 다양한 전략을 사용해야함을 반성하게 됩니다.
https://tech.kakaopay.com/post/msa-transaction/

결국은 결제의 멱등성을 위해 유니크키를 주고 받으면서 처리를 하는 내용을 써보기로 했습니다.

  public String createToken() {
        String token = UUID.randomUUID().toString();
        TrxToken trxToken = new TrxToken(token);
        trxTokenRepository.save(trxToken);
        return token;
    }

예상 시나리오는 사용자에게 미리 결제 토큰(키)를 발급해줍니다. 이 키는 주문번호, 시간등으로 대체할 수 있을 것 같습니다. 이번에는 임의로 uuid를 통해 전달을 한다고 가정했습니다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class TrxToken {

    @Id
    @Column(name = "trx_key")
    private String id;

    @Enumerated(EnumType.STRING)
    private TokenStatus tokenStatus;

    @Version
    private Long version;

    public TrxToken(String uuid) {
        this.id = uuid;
        this.tokenStatus = TokenStatus.PUBLISHED;
    }

    public void changeStatusUsed() {
        this.tokenStatus = TokenStatus.USED;
    }
}

낙관적 락을 사용하여 사용했는지 여부를 체크할 수 있게 만들었습니다. JPA를 사용하고 있기때문에 낙관적 락을 사용하는데 어려움이 있지 않았습니다.
받아온 토큰값으로 저장된 값과 비교하고, 주문 결제를 진행합니다. 티켓을 구매했다면 이벤트를 보내 사용자 티켓을 증가시킵니다.

일일 베스트셀러 기능

  • 개념만 세우고 다 개발하지 못했습니다.
  • 스프링 배치를 통해 00:00 기준으로 사용자 책에서 갱신된 내역이 많은 에피소드들의 정보로 일일 베스트설러를 만들면 될 것 같습니다.

'회고 모음 > Project' 카테고리의 다른 글

웹소설 서비스 만들기-5  (0) 2023.04.30
웹소설 서비스 만들기-4  (0) 2023.04.17
웹소설 서비스 만들기-2  (0) 2023.04.17
웹소설 서비스 만들기-1  (0) 2023.04.17
웹소설 서비스 만들기 - ERD  (0) 2023.04.05