장고 get_or_create()와 race condition 문제

2022. 3. 5. 12:29·Django
목차
  1. get_or_create 메소드 설명
  2. 레이스 컨디션 문제

get_or_create 메소드 설명

장고의 get_or_create 함수는 특정 kwargs로 데이터베이스 객체를 탐색하고 이를 불러오거나 존재하지 않는 경우 새롭게 생성하는 간편한 메소드입니다.

 

메소드 실행 결과 (object, created) 튜플이 반환됩니다. object는 불러온 객체이거나 생성된 객체이며, created는 불리언 값입니다.

 

이는 중복된 객체가 생성되는 것을 방지하고, 다음과 같은 로직을 한번에 처리할 수 있는 메소드입니다.

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()

여기서 인식해야 하는 개념은 위의 요청이 동시에 발생할 시 동일한 파라미터로 Person을 저장하려는 시도가 이뤄지는 race conditon이 발생할 수 있다는 것입니다. get_or_create()를 사용하면 기본적으로 이러한 race condition을 방지할 수 있습니다.

obj, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

레이스 컨디션 문제

앞서 get_or_create를 사용하면 race condition을 방지할 수 있다고 정리했습니다. 그러나 여기에는 데이터베이스 단에서 unique 또는 unique_together가 처리되어 있어야 한다는 전제가 있습니다. 그렇지 않은 경우, 메소드를 동시에 호출하면 동일한 파라미터를 가진 열이 중복해서 생성될 수 있습니다.

 

보다 정확하게는 unique 처리가 되지 않은 객체에서 하나의 스레드(탐색이 완료되고 아무런 결과가 리턴되지 않은 상황)를 통해 코드의 일부를 실행하는 중에 다른 스레드에서 객체가 생성될 경우 IntegrityError가 리턴되지 않아 두 개의 객체가 생성될 수 있습니다. 결론적으로 데이터베이스에는 두 개의 객체가 생성되는 의도치 않은 문제가 발생합니다.

 

따라서 데이터베이스 레벨에서 unique 제약이 추가되지 않은 객체에서는 get_or_create를 사용하지 않는 것이 좋습니다. 반대로, 이러한 제약이 추가되어 있다면 다수의 스레드를 통해 발생하는 race condition을 마주하지 않을 것이기 때문에 get_or_create를 사용하는 것이 더 좋을 수 있습니다.

 

참고 자료:

https://youngminz.netlify.app/posts/get-or-create-deadlock
https://adriennedomingus.medium.com/the-perils-of-get-or-create-race-conditions-485fc8fb2068
https://docs.djangoproject.com/en/4.0/ref/models/querysets/#get-or-create

반응형

'Django' 카테고리의 다른 글

장고 SECRET_KEY 관리 방법: 환경 변수와 로컬 파일 설정  (0) 2022.03.13
장고 개발 환경에 따라 settings.py 분리하는 방법  (0) 2022.03.13
장고 Q를 활용한 필터링, 정렬, 검색 방법  (0) 2022.02.20
장고에서 HTTP GET, POST 요청 처리하는 방법  (0) 2022.02.20
장고 ORM과 쿼리셋의 개념  (0) 2022.02.07
  1. get_or_create 메소드 설명
  2. 레이스 컨디션 문제
'Django' 카테고리의 다른 글
  • 장고 SECRET_KEY 관리 방법: 환경 변수와 로컬 파일 설정
  • 장고 개발 환경에 따라 settings.py 분리하는 방법
  • 장고 Q를 활용한 필터링, 정렬, 검색 방법
  • 장고에서 HTTP GET, POST 요청 처리하는 방법
휘 Hwi
휘 Hwi
개발자 성장 로그
  • 휘 Hwi
    개발자 로그: 변화를 위한 공간
    휘 Hwi
  • 전체
    오늘
    어제
    • 분류 전체보기 (61)
      • 101 (1)
      • Web | Internet (4)
      • HTML | CSS (4)
      • Python (9)
      • Django (20)
      • Javascript (0)
      • Node.js (0)
      • React (0)
      • React Native (0)
      • Database (1)
      • Git (1)
      • Terminal | Vim (1)
      • Auth | Security (4)
      • AWS (0)
      • Docker (0)
      • Kubernetest (1)
      • Deployment (1)
      • Project (2)
      • TIL (12)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    장고 Views
    HTTP GET 요청
    장고
    JWT 디코딩
    탭내빙
    TIL
    파이썬
    html
    깃 ssh
    요소 절대 크기
    깃 퍼블릭 키 등록
    새 탭에서 열기
    요소 상대 크기
    프로젝트 회고
    깃 오류
    정규 표현식
    target="_blank"
    HTTP
    깃 에러 해결
    요소 크기 설정
    장고 프로젝트
    css
    함수
    파라미터
    JWT 인코딩
    HTTP POST 요청
    장고 URL
    깃
    배포
    JWT
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
휘 Hwi
장고 get_or_create()와 race condition 문제
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.