스프링부트

[스프링부트] 개인 프로젝트 버그 고치기

컴공코딩러 2023. 8. 27. 11:46

링크

구글, 원스토어

나의 축구 지식테스트 앱이다...

 

일단 내 앱은 배포하고 돌아간 상태였고

 

DB를 확인해보니

똑같은 닉네임이 저장되고 있었다...

 

왜그럴까 확인해보았다...

 

내 앱은 이렇게 처음에 닉네임을 설정(체크) 하고 회원가입되는 순서로 진행된다.

동작순서는

프론트에서 닉네임을 입력후 설정하기 버튼을 누르면

API 순으로

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    @Operation(summary = "프론트유저 닉네임 조건설정 API")
    @PostMapping("/front-user/check")
    @ResponseBody
    public String CheckNickName(String nickName) {
        boolean matches = nickName.matches("[0-9|a-z|A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝]*");
        if (frontUserService.checkNickName(nickName))
            return "exits";
        else if (nickName.contains("운영자")||nickName.contains("admin"))
            return "noNickName";
        else if (nickName.isEmpty())
            return "empty";
        else if (nickName.length()>8)
            return "length";
        else if (!matches)
            return "notMatch";
        else
            return "OK";
    }
cs

 

에서 닉네임 체크를 하고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 var nickNameCheck: String = ""
            UserClient.retrofitService.nickNameCheck(nickName).enqueue(object : Callback<String> {
                override fun onResponse(call: Call<String>, response: Response<String>) {
                    nickNameCheck = response.body().toString()
                    if (nickNameCheck == "OK") {
                        UserClient.retrofitService.singUp(nickName)
                            .enqueue(object : Callback<Void> {
                                override fun onResponse(
                                    call: Call<Void>,
                                    response: Response<Void>
                                ) {
                                    if (response.isSuccessful) {
                                        MySharedPreferences.setUserId(this@SignupActivity, nickName)
                                        presenter.view.onLogin()
                                    }
                                }
cs

프론트 (안드로이드 앱) 에서는 닉네임체크 함수에 OK 메세지가 왔을때 singup 요청을 날린다

1
2
3
4
5
6
7
8
9
10
 @Operation(summary = "스프링 시큐리티 회원가입")
    @PostMapping("/user")
    public String signup(UserInfoDto infoDto) { // 회원 추가
        String userId = infoDto.getUserId();
        return "redirect:/login";
    }
cs

 

동작과정은 닉네임 입력 -> check - >이상없음 singup -> 메인화면

순으로 진행되지만 로컬에서 테스트했을땐 한번도 문제점을 발견하지 못했다.

하지만 실제 서비스 환경에서

위에 이미지처럼 중복 닉네임이 들어오고 있었다.

 

일단 첫번째로 nick_name 컬럼에 unique는 일부러 걸지 않았다(정말임)

코드단에서 해결해보고 싶었고 로컬에서 문제가 없어서 서비스 중에도 문제가 없을것 같았다.

(서비스 초기엔 심지어 발견 못함)

 

일단 중복저장되는 첫번째 이유는 당연하지만 컬럼에 unique가 걸리지 않아 중복 저장되고 있다.

 

만약 쿼리가 여러번 날아와도 닉네임이 중복된다면 저장되지 않기 때문에 문제가 발생하지 않는다.

 

그래서 그냥 컬럼에 unique를 걸면 간단히 해결되지만..

 

하지만 난 이런 해결방법을 원하지 않았다.

 

어째서 코드단에서 문제가 발견했는지 찾아보고 싶었다.

 

일단 사용자가 왜 여러번 요청을 날리는지 부터 확인해야했다.

 

이유는...

 

aws서버가 느려서였다.. 사용자는 요청에 대한 대답이 느려 사용자는 닉네임중복체크 버튼을 연타하고있었던 것이었다..

(따딱 문제라고 한다! 내 서버에서는 따다닥까지 봤다.. )

 

하지만 나는 코드단에서 분명히 체크를 하고있었는데 왜이런 문제가 발생했을까...

 

 

 

나랑 비슷한 고민을 가졌던 사람이 있었다.

이 질문에 대한 대답은 다른 링크에 달아 놓으셨다고 해서 다른 링크를 들어갔다!!

 

질문2

 

 

 

아래는 인프런 김영한 님의 답변이다! (나는 김영한님의 강의를 3개나 들어봐서 답변이 참 신뢰가 간다..)

라는 답변!!!

정말 도움이 되었고 물론 나도 select을 날려 중복체크를 하지만 서버 성능문제가 있기때문에

결국 컬럼에 unique를 걸어서 문제를 해결했다!.