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

Release에서 회원가입이 중복으로 일어나는 Issue #259

Open
60jong opened this issue Apr 7, 2023 · 1 comment
Open

Release에서 회원가입이 중복으로 일어나는 Issue #259

60jong opened this issue Apr 7, 2023 · 1 comment

Comments

@60jong
Copy link
Collaborator

60jong commented Apr 7, 2023

Todoary 릴리즈 후, 회원가입이 중복으로 일어나는 경우가 많이 보입니다. (현재는 일일이 대조 후 중복된 계정 중 미사용 계정은 모두 삭제했습니다.)

그 원인으로, 회원가입 버튼이 중복으로 눌려서 여러 차례 Request가 보내진 것으로 보입니다.

똑같은 상황을 테스트 해보았습니다.

동시성 테스트 by JUnit5

테스트 코드

  • develop-rds 환경에서 테스트했습니다.
  • 10개의 쓰레드를 통해 동시에 Apple OAuth User를 저장해보았습니다.
@Transactional
@SpringBootTest
public class ConcurrencyTest {
    @Autowired
    MemberService memberService;

    @Autowired
    EntityManager em;

    @Test
    public void 회원_동시성_테스트() throws Exception {
        String name = "concurrencyName";
        String email = "concurrencyEmail";
        String providerId = "concurrencyProviderId";
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> memberService.joinOauthMember(
                    createOauthMemberParam(name, email, ProviderAccount.appleFrom(providerId)))
            );
        }

        executorService.shutdown();
        executorService.awaitTermination(10, TimeUnit.SECONDS);

        List<Member> members = em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();

        members.stream()
                .map(member -> member.getId())
                .forEach(System.out::println);
        Assertions.assertThat(members.size()).isGreaterThan(1);
    }

    OauthMemberJoinParam createOauthMemberParam(String name, String email, ProviderAccount providerAccount) {
        return new OauthMemberJoinParam(name, email, providerAccount, "ROLE_USER", true);
    }
}

문제 상황 확인

  • console에 member id 출력 결과

스크린샷 2023-04-08 011204

  • 실제 DB 상황

스크린샷 2023-04-08 011151

왜 10명이 아니라 9명이 생겼는지는 모르겠지만... 중복 계정이 생기는 것을 확인했습니다. (중복 request가 보내진 것이 맞아 보입니다.)

문제 해결

어떻게 해결하면 좋을 지 의견 부탁드립니다. @Todoary/todoary_serverdeveloper
(일단 아래의 mysql 커맨드로 해결은 했습니다.)

ALTER TABLE member ADD UNIQUE unique_name (email, provider);

결과 확인

  • console에 member id 출력

스크린샷 2023-04-08 011917

  • 실제 DB 상황

스크린샷 2023-04-08 011929

결론

일단 DB에서 (member의 name & provider) set을 unique하게 함으로써 해결했지만, 실제 서비스에서 중복 요청이 또 들어오게 되면 예외 메시지가 앱에서 뜰 것이기에 중복 요청이 못 가도록 앱 버튼에 처리가 따로 필요해보입니다. @Todoary/todoary_iosdeveloper @yooyeri

@melonturtle
Copy link
Member

melonturtle commented Apr 7, 2023

아 버튼 중복으로 눌리는거 때문에 프론트에 버튼 클릭 후에 일시적으로 요청 안가게 막는 것 추가해달라고 해서 추가됐었는데... 회원가입 버튼엔 안됐던건지 모르겠네요 @Todoary/todoary_iosdeveloper

unique 해놓는건 좋은 것 같습니다!

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

No branches or pull requests

2 participants