Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/distribute lock #11

Open
wants to merge 30 commits into
base: feature/order
Choose a base branch
from

Conversation

haxr369
Copy link
Contributor

@haxr369 haxr369 commented May 2, 2024

개요

애플리케이션이 관리하는 락을 이용해서 서로 다른 세션에서 동일한 락을 사용할 수 있도록 합니다.

변경 사항

추가 정보

  • 각 주문마다 유니크한 분산락을 사용해야하기 때문에 PaymentStatusDtoCustomerRequestDto buyer를 추가하여 어떤 고객이 결제 요청을 했는지 추가해야합니다.
  • 현재 분산락은 고객의 이메일을 이용해 주문에 대한 스레드 안전성을 보장합니다.
  • 아래 같이 동시 주문을 생성해도 안전하게 주문을 처리할 수 있습니다.
for i in {1..4}; do
  curl --location 'http://localhost:8080/order' \
  --header 'Content-Type: application/json' \
  --data-raw '{
      "core_products" : {
          "1": 2
      },
      "buyer" : {
          "email" : "user'$i'@naver.com",
          "name" : "user'$i'"
      },
      "client_type" : "InexperiencedCustomer",
      "payment_method" : "CREDIT_CARD"
  }' &
done

1. 주문 서버에 대한 관심사를 작성
🐛 Fix : 오류 수정
✅ Test : 테스트 코드 추가

1. 클라이언트 주문 요청 API 작성
2. 공통 응답 생성
3. exception handler 생성
✅ Test : 테스트 코드 추가
1. Product 도메인에 재고 확인 기능 추가
    클라이언트가 요청한 상품의 재고가 충분한지 확인할 수 있다.
2. 재고 확인 기능의 test 코드 추가
1. 주문 서비스 작성
1. DB 상에서 유형제품과 주문이 연결되긴 하지만 출력에 연결되지 않는 것처럼 보이는 문제 발생
	재고 감소 기능 구현

To Do

재고 감소 테스트
🐛 Fix : 한 Transcation에서 생성 확인이 어려운 문제 해결
🤖 Refactor : 메서드 분리
	유형제품 제고 확인 테스트 작성
✅ Test : 비관적 락과 낙관적 락을 통해 재고 감소 기능 테스트
To Do
paymentId를 리다이렉트할 때 이용해서 결제가 정상적으로 이뤄졌는지 확인하기
To Do
결제 확인 기능 구현
결제 실패 시 롤백 기능 구현
To Do

1. 클라이언트에게 결제 결과 보여주도록 리다이렉트 성공시키기
2. 결제 실패시 롤백하는 로직 작성하기
결제 서버 작성, 결제 응답에 따라 주문 로직 구현

To Do

네임드락을 이용해서 다른 세션에서 같은 락 사용해서 긴 생명 주기 transaction 구현
분산락은 단순히 여러 컴포넌트에서 접근할 수 있는 이름이 있는 락일 뿐 자동 롤백 같은 역할을 하지 않는다.
다만, 여러 컴포넌트가 락을 얻어 동시성 문제를 해결하는데는 도움을 받을 수 있을 것 같다.
To Do
1. 롤백은 되었지만 클라이언트가 리다이렉트해서 받은 결과는 롤백 전 상태를 받는다.
2. 따라서 클라이언트의 세션과 결제 완료 세션은 다른 락을 가지고 DB에 접근해야하고 결제 완료 세션이 우션해야한다.
To Do

1. 결제 실패가 올 때 롤백하고 클라이언트에게 응답할 수 있도록 수정
2. 주문 수량에 상관 없이 일정하게 롤백이 가능하도록 수정
주문 생성과 주문 확정 사이 동시성 문제가 발생했다.
그러나 유저 레벨 락을 이용해서 스레드 안전하게 주문을 조작하게 했다.

To Do
1. 나머지 코드 정리
2. 결제가 실패나 성공 아무거나 떠도 안전하게 처리할 수 있도록
이유 : JPA 연관관계 이해 부족과 JPQL 쿼리 작성 실수
1. 결제 실패로 주문과 유형 제품의 1:N 연관관계 맵핑을 해제한다.
2. 결제 결과를 반환하기 위해 주문과 유형제품의 Fatch Join된 쿼리를 발생
3. 유형제품과 연관된 주문이 없기 때문에 주문을 찾지 못함.

To Do
현재 락을 거는 기준은 임의의 1L의 payment id로 걸고 있다.
즉, 모든 주문 생성이 같은 락을 사용하는 것.
이 경우 여러 주문 생성이 올 경우 데드락이 발생할 수 있다.

따라서 주문에 따라 락을 다르게 지정해줘야한다.
To Do

동시 요청 시 core_product에 대한 동시성 문제가 생기는 것으로 보인다.
분명 2개 주문 요청에 대해 성공했다고 로그가 찍히는데 정작 DB에 core_product의 재고가 줄어들지 않았다.
현재 여러 클라이언트가 동시에 한 핵심 상품을 구매하려고 할 때 비관적 락을 사용했더니 롤백이 씹히는 문제가 있다.
crul을 중첩해서 동일한 핵심 상품을 동시에 주문했을 때 정상적으로 스레드 안전하게 주문 생성과 결제 결과에 따른 롤백 그리고 결과 응답이 보여집니다!!!!!!!
롤백 메서드에서 불필요하게 주문과 유형 상품에 비관적 락을 걸지 않도록 수정
1. 유형 상품과 핵심 상품의 fetch 설정을 Lazy로 설정
2. 주문과 유형 상품만 fetch join으로 한번에 쿼리 그리고 핵심 상품은 비관적 락을 걸어 따로 쿼리
	그 결과 락을 무분별하게 사용하지 않고 필요한 곳에만 사용하게함.
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.

1 participant