데이터베이스가 있고 REST API 서버의 ORM 을 사용해서 CRUD 를 하는 서버가 있다고 가정하자
(사실 대부분이 그렇다.)
Read 를 제외한 나머지 Create , Update , Delete 는
왠만하면 트랜잭션을 걸고 에러가 나면 롤백을 하고 모든 에러가 없다고 판단이 되면 커밋을 하는 방식일거다.
위의 로직을 유저 테이블로 예제로 예를 들면 회원가입 API 에서는
유저 생성 -> ( 참조테이블 핸들링 , 뭐 어떤거, 뭐 어떤거 Update , 뭐시기 ) -> 유저테이블 쿼리 -> 반환
이런 로직일텐데
동기 코드로 짯다고 하면 (문법적 에러가 없고 데이터베이스 , ORM 모두 연결이 잘 설정 되어 있다고 가정)
분명 동기코드로 커밋을 했는데 유저테이블 쿼리를 할때 record not found 가 떳다.
해당 에러를 확인한 후 디비 조회를 하니 record 가 있었다.
대가리 속엔 ㄹㅇ 뭥미 만 존재할뿐 왜 안되는지 정말 이해가 하나도 안갔다.
모든 환경은 클라우드에서 동작하고 있었으니
aws VPC , nacl , 보안그룹 , ec2 보안그룹 , rds VPC , rds 보안그룹 , IAM 등등
애먼곳에서 문제를 찾다가 이게 원인이 아니라는걸 알고
코드만 한참 봤다.
늘 봐왔던 코드인데 외 않되
ORM 을 사용하면서 이런 문제는 한번도 없었다.
분명 코드는 동기로 돌아간다.
커밋이 잘 되었고 데이터베이스에 값도 들어갔으니 연결문제는 아니다.
....
...
!
결론부터 말하자면 내 소스코드만 동기였지 내 서버와 데이터베이스는 동기적으로 연결된게 아니다.
이게 무슨말이냐면
서버에서 ORM 으로 유저를 생성하고 커밋을 하고 조회를 하는데
커밋을 분명히 하고 ORM 은 데이터베이스로 트랜잭션을 넘겨준 상태에서
데이터베이스에 기록이 되기전에 그 찰나의 몇 밀리세컨드차이로 서버가 연산이 더 빨라서 조회를 먼저 한게 문제였다.
!
내가 사용했던 REST API 서버는 golang 의 Gin Framework 를 사용중이었다.
뭐 쨋든 해결책으로는 I fixed it 해결책과 근본적인 해결책이 있다.
처음에는 단순하게 해결책으로 0.5초 정도 데이터베이스에 트랜잭션이 커밋되는 시간을 두고
쿼리를 조회하는 방식으로 해결하려 했으나
위와 같은 느낌이 쉬지 않고 들기에 정확한 리팩토링이 필요했다.
문제는 생각하니 의외로 간단했다.
단순히 조회까지 트랜잭션으로 상태관리를 넣은 후 커밋을 해주면
이미 그 상태는 유저 생성 한 상태를 기록하고 있으니 쿼리도 가능하게 된다.
기존은 쿼리 이전에 커밋을 했었고 리팩토링 한후는 쿼리 이후에 커밋을 해줬다.
예상대로 오류는 해결 됐고 나는 천재가 되었다.
끝
---
고작 6개월전에 쓴글이 지금와서 보면 정말 너무나 당연한 로직을 가지고 글을 썻구나 생각한다.
'RDS' 카테고리의 다른 글
사용자 차단 쿼리를 어떻게 짤까? (RDS) (0) | 2022.04.21 |
---|