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

#346 [feat] 모임명 중복 처리 분산락 적용 #359

Merged
merged 7 commits into from
Jun 13, 2024
Merged

Conversation

sohyundoh
Copy link
Member

@sohyundoh sohyundoh commented May 30, 2024

✒️ 관련 이슈번호

Key Changes 🔑

  1. 글모임명 중복체크에 이용되는 메서드에 적용할 어노테이션 생성
    package com.mile.moim.service.lock;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AtomicValidateUniqueMoimName {
    }
  2. Aspect 클래스 작성
    package com.mile.moim.service.lock;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AtomicValidateUniqueMoimName {
    }
    • Around를 통해 transaction을 전한 후 finally 블럭에서 lock을 해제해주는 방식 사용
  3. Propagation.REQUIRES_NEW 옵션을 지정해 부모 트랜잭션의 유무에 관계없이 별도의 트랜잭션으로 동작하게끔 설정하였습니다.
    • @Transactional(propagation = Propagation.REQUIRES_NEW)
      public Object proceed(final ProceedingJoinPoint joinPoint) throws Throwable {
      return joinPoint.proceed();
    • 트랜잭션의 커밋 시점과 락의 해제시점이 다를 경우 정합성 문제가 발생할 수 있어 이렇게 별도의 트랜잭션을 활용하여 사이드 이펙트를 없앴습니다.
    • 따라서 Transactional 어노테이션을 직접 적용하지 않았습니다.
  4. 테스트 코드 작성
    • 글 중복생성과 동일하게 MockMvc를 활용하여 테스트 코드를 작성하였습니다.

To Reviewers 📢

@sohyundoh sohyundoh self-assigned this May 30, 2024
Copy link
Contributor

@parkheeddong parkheeddong left a comment

Choose a reason for hiding this comment

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

분산락 작업 너무 고생하셨습니다 :> LGTM ... 🤍 궁금한 부분 코멘트로 남겨두었습니다!

public MoimCreateResponse createMoim(
final Long userId,
final MoimCreateRequest createRequest
) {
checkMoimNameUnique(createRequest.moimName());
Copy link
Contributor

Choose a reason for hiding this comment

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

P5) (제가 이해한 바에 따르면).. 분산락은 현재 메서드 별로 생성되고 있는데, 중복 확인을 수행하는 메서드가 여러 개 있다면 락의 효과가 감소하지 않나요!? 예를 들어서 두 유저가 동시에 각각 같은 이름으로 글모임 수정/글모임 생성을 요청한다고 가정해 본다면. 한 유저는 글모임 수정을 할 때 validateMoimName 메서드가 호출되고, 한 유저는 글모임 생성할 때 동시에 checkMoimNameUnique가 호출된다면, 락은 각각 다른 이름의 키로 별도이기 때문에 분산락의 효과가 없지 않는지 궁금합니닷...

Copy link
Contributor

Choose a reason for hiding this comment

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

P5) 그래서 제가 생각했을 땐 validateMoimName과 checkMoimNameUnique에서 이뤄지고 있는 중복확인 로직을 단일 메서드로 통일해야 분산락의 효과를 볼 수 있지 않나 싶었는데요..! 그렇게 되면 createMoim이나 modifyMoiminformation에 @AtomicValidateUniqueMoimName 어노테이션을 붙일 필요 없이, 중복확인용 메서드에만 어노테이션을 붙여서 모든 중복확인이 동일한 락을 사용하게 하면 되지 않을까 싶습니다

Copy link
Member Author

Choose a reason for hiding this comment

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

흠 이 부분에서 제가 실수한 부분이 있었습니다! 모든 메서드에서 락을 걸고 joinpoint에서 signature로 락을 걸면 안됐는데요! 이 부분 수정하겠습니다! :) 감사합니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

중복 체크 메서드에만 락을 걸어주는 것은 맞지 않습니다!
그 이유는 자원의 생성과 중복 체크가 동시에 일어날 수 있기 때문에 분산락을 적용한 것인데, 중복 체크만 락을 걸어줄 경우 그 사이에 이름의 자원이 생성되었을 때에는 원자성을 보장하지 못하기 때문입니다!
그래서 어노테이션을 통해서 락의 범위를 정해준 것입니다!

}

public void checkAvailability(final Boolean available) {
if (!available) throw new RuntimeException("Lock is Unavailable");
Copy link
Contributor

Choose a reason for hiding this comment

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

P5) Error Message로 만들어주는 게 어떨까용?

@parkheeddong parkheeddong self-requested a review June 13, 2024 13:58
Copy link
Contributor

@parkheeddong parkheeddong left a comment

Choose a reason for hiding this comment

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

이해완 -!! 고생하셨습니다!

@sohyundoh sohyundoh merged commit 1be1e55 into develop Jun 13, 2024
1 check passed
@sohyundoh sohyundoh deleted the feat/#346 branch June 13, 2024 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] 모임 이름 중복 검사 분산 락 사용
2 participants