Skip to content

Conversation

@Rayoungji
Copy link

  1. Redisson 분산락을 사용하여 동시성 제어 로직을 구현하였습니다.
  • 여러 블로그들을 참고하며 구현하였는데 추후에 더 자세하게 학습후 정리하도록 하겠습니다!
  1. Facade 패턴을 적용하여 코드 작성을 하였습니다.

  2. 구매 로직에 대한 테스트 코드를 작성하였습니다.

  • Redisson 분산락을 사용하였을 경우와 사용하지 않았을 경우 두가지 케이스에 대해 테스트 코드 작성을 진행하였습니다. 테스트 코드를 제대로 구현해본적이 없어서 미흡한 부분이 있는점 참고부탁드립니다..! 🙇‍♀️

@Rayoungji Rayoungji requested review from JoeCP17, minsoozz and yyy96 March 22, 2023 13:40
Copy link
Contributor

@minsoozz minsoozz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 보면서 많이 배웠어요~ 고생하셨습니다 👍

@@ -0,0 +1,28 @@
package com.week.zumgnmarket.entity;

import lombok.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사람마다 견해가 다르지만 import 문에서 와일드카드는 지양하는 편입니다.
참고해서 링크 드릴게요

https://dev.to/kingori/import-5531

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스에 @Builder 어노테이션을 추가하신 이유를 알 수 있을까요?

public void decrease() {
final String thread = Thread.currentThread().getName();
if((this.ticketCount - 1) < 0 ){
//throw new RuntimeException("오늘자 티켓팅이 마감되었습니다 (재고 부족)"); - 테스트 위해 주석
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

불필요한 코드와 주석은 과감하게 삭제하는 것도 좋을 것 같아요~
어차피 Git 에서 버전 관리를 해주고 있으니까요

Musical musical = musicalTicketService.findMusicalById(ticketRequest.getMusicalId());
MusicalTicket musicalTicket = musicalTicketService.findTicketByMusical(musical);
if (!musicalTicket.checkTicketingDate(ticketRequest.getTicketingDate())) {
throw new RuntimeException("지금은 티켓팅 기간이 아닙니다.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RuntimeException 으로 예외를 처리하는 것보다는 티켓팅 기간이 아니라는 적절한 예외로 포장하는 것이 좋아보여요~

Buyer buyer = buyerService.findBuyerById(ticketRequest.getBuyerId());
Musical musical = musicalTicketService.findMusicalById(ticketRequest.getMusicalId());
MusicalTicket musicalTicket = musicalTicketService.findTicketByMusical(musical);
if (!musicalTicket.checkTicketingDate(ticketRequest.getTicketingDate())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 조건문도 명확하게 메소드로 추상화 할 수 있을 것 같습니다.


@Test
@Order(1)
void 락0_150명이_티켓팅을_실행() throws InterruptedException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

분산 락 개념이 정말 어렵던데 잘 구현해주셨네요 👍

@Column(name = "ticketing_date")
private LocalDate ticketingDate;

public static MusicalTicket of(Musical musical, Long ticketCount, LocalDate ticketingDate) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로젝트를 보면 정적 팩토리 메소드로 객체를 생성하는 방법과, 빌더 패턴으로 객체를 생성하는 방법
이렇게 두가지를 사용하시는 것 같은데 이것을 구분하는 기준이 있으신가요?

log.error("진행중인 사람 : {}, 메세지 : 티켓팅을 성공하셨습니다(남은 티켓 갯수 - {} 개) ", thread, this.ticketCount);
}

public boolean checkTicketingDate(LocalDate localDate) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프레디케이트 메소드는 자바 메소드 규약에 맞게 is~ , has~ 로 통일하는 방법도 있습니다~!

}
RLock lock = redissonClient.getLock(musical.getTitle() + ":" + ticketRequest.getTicketingDate());
try {
if (!lock.tryLock(3, 5, TimeUnit.SECONDS)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

락의 획득시도 시간, 락 점유 시간을 선택하신 기준이 있으신가요? 저도 동시성 이슈는 부족해서
영지님만의 기준이 있는지 궁굼해서 여쭤봅니다!

return musicalJpaRepository.save(musical);
}

public MusicalTicket findTicketByMusical(Musical musical) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 메소드는 조회 전용 쿼리로 보여서 readonly=true 옵션 또는 조회 전용 클래스를 만드는 것도 좋을 것 같습니다~!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants