본문 바로가기
Projects/D'ONE - 개인프로젝트

트러블슈팅 : 목표에 오늘의 DONE기록시 동시성 문제로 인한 중복 생성 (1/2)

by 우인입니다 2024. 7. 31.

문제상황

  1. 동시에 done 테이블에 접근하여 오늘 생성된 데이터가 있는지 조회
  2. 각 요청 모두 조회된 데이터가 없다고 판단
  3. 하루에 하나만 존재해야하는 데이터가 두개가 동시에 생성됨
한마디로, 우연히 두개의 요청이 동시에 조회하여 발생한 이슈

 

 

 

시도한 방법 - 비관적 락 적용

  • 오늘 해당목표의 수행기록(DONE)이 있는지 체크하는 쿼리에 비관적 락을 적용하였다.
  • 이로 인하여 동시에 들어오더라도 존재를 확인하는 조회쿼리의 레코드에 비관적 락을 걸어 하나의 트랜잭션이 끝난 이후 다른 트랜잭션에서 조회가 이뤄지도록 했다.

테스트

임시로 오늘 done의 여부를 조회하는 쿼리뒤에 3초의 대기시간을 두었다.

 

비관적락을 적용한 해당 목표에 오늘 생성된 done이 있는지 조회하는 쿼리.

 

curl을 통해 동시에 요청을 보냈다.

 

테스트 결과

 

1. 우선 두 요청의 select 쿼리가 동시에 발생

 

2. 첫번째 요청의 트랜잭션이 진행되어 새로운 done 데이터를 저장하고 트랜잭션이 종료

 

 

3. 대기중이었던 조회가 비관적 락을 얻어 조회를 실시. 데이터 존재 확인 후 예외 발생 후 종료됨.

 

4. 하나의 데이터만 생성

 

 

고려사항 1 - 다른 done을 조회하는 요청들까지 영향을 주는가?

예를 들어, goal_id가 1인 done을 조회하는 레코드에 비관적 락이 걸렸을때 goal_id가 2인 done을 조회하는 쿼리도 비관적 락을 얻기위해 대기를 하는지가 우려되었다.

 

테스트

 

테스트 결과

데드락 발생

 

1에 대한 요청 2개 중 하나만 저장이 완료

 

서로 같은 테이블에 insert intention이 레코드락에 대해 대기하고 있다.

 

앞서 비관적락으로 쓰기락을 서로의 트랜잭션이 갖고 있고, 그 락을 얻기위해 서로 무한대기에 빠진 모습이다.

 

 

 

 

 

 

결과 기대했으나 아직 수정중

결국에는 이러한 방식을 희망한다... 실패 (07/30)

  • 위와 같은 방식으로 동작되게 변경하고자 함.
  • 하지만, 다른 데이터를 동시에 insert하는 경우 데드락이 발생.
    • FK로 설정되어 동일한 인덱스페이지에 레코드락이 걸려 서로 무한 대기하는 것으로 보임.
  • 분산락으로 중복요청 해결함 (다음글)
 

트러블슈팅 : 목표에 오늘의 DONE 기록시 중복요청 분산락으로 방지하기 (2/2)

https://thiswooin.tistory.com/147 트러블슈팅 : 목표에 오늘의 DONE기록시 동시성 문제로 인한 중복 생성 (1/2)문제상황동시에 done 테이블에 접근하여 오늘 생성된 데이터가 있는지 조회각 요청 모두 조회

thiswooin.tistory.com