Coupon 생성과 Query

두주·2024년 2월 17일
0

TIL

목록 보기
55/58

Create Coupon

사실 CRUD는 이제 뭐 할 게 없다.

    @Transactional
    override fun createCoupons(request: AddCouponRequest) {
        val issuedBy = memberRepository.findByIdOrNull(/*userPrincipal.id*/1L)
            ?: throw IllegalArgumentException("Invalid Member")

        val coupons = mutableListOf<CouponEntity>()

        for (i in 0 .. request.howManyMake) {
            coupons.add(CouponEntity(
                content = request.content,
                couponNumber = couponUtility.createCouponNumber(),
                couponExp = request.couponExp,
                issuedBy = issuedBy, // 쿠폰 발급한 사람 나중에 security 적용되면 토큰 접속 정보 넣을 것
                memberId = null, // 여기엔 쿠폰 사용한 사람이나 발급받은 사람 정보가 들어갈 거임
                available = true
            ))
        }

        couponRepository.saveAll(coupons)

요청하는 수 만큼의 쿠폰을 생성한다.

쿠폰 발급시에는 아래와 같은 정보가 필요하다
content : 쿠폰 내용 (런칭 기념 쿠폰, 전사 임직원 쿠폰 등)
couponNumber : 쿠폰 번호 (16자리의 개별 난수 쿠폰 번호, 중복 불가)
couponExp : 쿠폰 유효 기간 (생성일로부터 n일간 유효할 것인지)
issuedBy : 쿠폰 생성자
memberId : 쿠폰 소유자 (쿠폰을 입력한 사람, 생성때는 null, 등록 시 등록 유저 id)
available : 사용 가능 여부

해야될 것

지금 내용을 정리하며 써 보니 쿠폰을 통해 획득할 수 있는 보상 테이블이 없다.
근데 이 내용이 db에 들어가야될지, 해당 쿠폰에 대한 처리를 따로 적용할 지 모르겠다.

내 생각에는 해당 쿠폰을 사용했을 때 어떤 효과가 있을 지에 대해서는
DB에서 저장하는 것이 아니라 별도의 쿠폰 관리 클래스가 있어야 하지 않을까?

문제점

[Hibernate] 
    insert 
    into
        coupon
        (available, content, coupon_exp, coupon_number, created_at, issued_by, member_id, updated_at) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?)
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (1:BOOLEAN) <- [true]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (2:VARCHAR) <- [임직원 쿠폰]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (3:INTEGER) <- [1]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (4:VARCHAR) <- [D1QPL1IKT3YRY857]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (5:TIMESTAMP) <- [2024-02-18T01:12:42.698748400]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (6:BIGINT) <- [1]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (7:BIGINT) <- [1]
2024-02-18T01:12:42.699+09:00 TRACE 7964 --- [nio-8080-exec-6] org.hibernate.orm.jdbc.bind              : binding parameter (8:TIMESTAMP) <- [2024-02-18T01:12:42.698748400]
[Hibernate] 
    insert 
    into
        coupon
        (available, content, coupon_exp, coupon_number, created_at, issued_by, member_id, updated_at) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?)

내가 쿠폰을 150개 생성하겠다 요청하였을 때 위와 같은 쿼리문이 150번이 출력된다.
save한 만큼 나가는 거니까 사실 매우 정상적인 일이겠지만,
이걸 어떻게든 줄여보고 싶어 여러 방법을 사용해 보았다.

1. saveAll 사용해 보기

        val coupons = mutableListOf<CouponEntity>()

        for (i in 0 .. request.howManyMake) {
            coupons.add(CouponEntity(
                content = request.content,
                couponNumber = couponUtility.createCouponNumber(),
                couponExp = request.couponExp,
                issuedBy = issuedBy, // 쿠폰 발급한 사람 나중에 security 적용되면 토큰 접속 정보 넣을 것
                memberId = null, // 여기엔 쿠폰 사용한 사람이나 발급받은 사람 정보가 들어갈 거임
                available = true
            ))
        }

먼저, 생성한 쿠폰을 mutableList에 먼저 저장해 둔다.

그리고 생성이 완료되었을 때 saveAll coupons를 통해 리스트를 db에 저장한다.

이렇게 해도 결국 쿼리문은 150번 발생했다.

리스트 자체를 저장하는 것이 아니라 그 내용물을 결국 하나씩 저장하기에
쿼리문이 150번 발생하는 것이 정상이다.

2. 어쩔 수 없이 150번 쿼리문이 나간다면

사실 150개의 쿼리문은 적은 수준이라고 생각헀다.

고민된 내용을 정리하면 크게 3가지 정도가 있었다.

1) 대형 서비스에서 10만개의 쿠폰 발급이 필요하다면 어떻게 해야할까?

2) 10만개의 쿼리문이 발생하는 동안, 에러나 동일한 쿠폰 번호가 발생하여 등록이
불가한 경우에는 시스템의 흐름이 어떻게 진행될까?

3) 1000건씩 끊어가며 확실히 데이터가 저장되었는지 확인하고, 검증하면서 발급할 수 있을까?


추가적으로 공부해야 될 내용들이 너무 많다

아직 모든 내용을 공부하고 학습하지 못했음에도 TIL을 쓰는 이유는
위와 같은 고민을 해결하기 위해 계속 리마인드하기 위함이다.

profile
야옹.

0개의 댓글