개요
이 가이드에서는 Django MongoDB 백엔드를 사용하여 트랜잭션을 수행하는 방법을 학습 수 있습니다. 트랜잭션을 사용하면 전체 트랜잭션 이 커밋된 경우에만 데이터를 변경하는 일련의 작업을 실행 수 있습니다. 트랜잭션 의 작업이 성공하지 못하면 Django MongoDB 백엔드는 트랜잭션 중지하고 데이터에 대한 모든 변경 사항이 표시되기 전에 삭제합니다. 이 기능 원자성 이라고 합니다.
MongoDB 에서 트랜잭션은 논리적 세션 내에서 실행 . 세션은 순차적으로 실행 하려는 관련 읽기 또는 쓰기 (write) 작업을 그룹화한 것입니다. 세션을 사용하면 작업 그룹 에 인과적 일관성 활성화 원자성, 일관성, 격리 및 내구성에 대한 기대치를 충족하는 트랜잭션 인 ACID 호환 트랜잭션 에서 작업을 실행 수 있습니다.
장고의 네이티브 트랜잭션 API 지원되지 않지만, 장고 MongoDB 백엔드는 동일한 기능을 활성화하는 사용자 지정 트랜잭션 API 제공합니다. 트랜잭션 내에서 작업을 실행 하려면 원자적 코드 차단 내에서 정의합니다. Django MongoDB 백엔드는 세션 로직을 내부적으로 관리하므로 트랜잭션 실행 전에 세션을 수동으로 시작할 필요가 없습니다.
중요
트랜잭션 제한
장고 MongoDB 백엔드의 트랜잭션 API 몇 가지 제한 사항이 있습니다. 제한 사항 목록을 보려면 장고 및 MongoDB 기능 호환성 가이드에서 데이터베이스 및 컬렉션 지원 을 참조하세요.
샘플 데이터
Movie
sample_mflix.movies
이 가이드 의 예제에서는Atlas 샘플 데이터 세트의 컬렉션 나타내는 모델을 사용합니다. Movie
모델 클래스의 정의는 다음과 같습니다.
from django.db import models from django_mongodb_backend.fields import ArrayField class Movie(models.Model): title = models.CharField(max_length=200) plot = models.TextField(blank=True) runtime = models.IntegerField(default=0) released = models.DateTimeField("release date", null=True, blank=True) genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) class Meta: db_table = "movies" managed = False def __str__(self): return self.title
Movie
모델에는 모델 메타데이터 지정하는 내부 Meta
클래스와 모델의 문자열 표현을 정의하는 __str__()
메서드가 포함되어 있습니다. 이러한 모델 기능에 대해 학습 모델 생성 가이드 에서 모델 정의를 참조하세요.
코드 예제 실행
Python 대화 셸 사용하여 코드 예제를 실행 수 있습니다. 셸 에 들어가려면 프로젝트의 루트 디렉토리 에서 다음 명령을 실행 .
python manage.py shell
Python 셸 입력한 후 다음 모델 및 모듈을 가져와야 합니다.
from <your application name>.models import Movie from django.utils import timezone from datetime import datetime
Movie
모델과 Python 인터랙티브 셸 사용하여 MongoDB 문서와 상호 작용 장고 애플리케이션 만드는 방법을 학습하려면 시작하기 튜토리얼을 참조하세요.
트랜잭션 시작
데이터베이스 트랜잭션 시작하려면 django_mongodb_backend.transaction.atomic()
함수를 호출합니다. 이 함수를 데코레이터 또는 컨텍스트 관리자로 사용할 수 있습니다.
다음 가져오기 성명서 사용하여 transaction
모듈을 가져와야 합니다.
from django_mongodb_backend import transaction
데코레이터 사용
함수 위에 @transaction.atomic
데코레이터를 추가하여 데이터베이스 트랜잭션 시작할 수 있습니다. 이 데코레이터는 함수 내 모든 데이터베이스 작업의 원자성을 보장 . 함수가 성공적으로 완료되면 변경 사항이 MongoDB 에 커밋됩니다.
다음 예시 트랜잭션 성공하면 sample_mflix.movies
컬렉션 에 문서 삽입하는 트랜잭션 내에서 create()
메서드를 호출합니다.
def insert_movie_transaction(): Movie.objects.create( title="Poor Things", runtime=141, genres=["Comedy", "Romance"] )
컨텍스트 관리자 사용
또는 transaction.atomic()
컨텍스트 관리자를 사용하여 원자적 코드 차단 만들 수 있습니다. 이 예시 앞의 예시 와 동일한 작업을 실행하지만 컨텍스트 관리자를 사용하여 트랜잭션 시작합니다.
def insert_movie_transaction(): with transaction.atomic(): Movie.objects.create( title="Poor Things", runtime=141, genres=["Comedy", "Romance"] )
트랜잭션 후 콜백 실행
트랜잭션 성공적으로 완료된 경우에만 특정 작업을 수행하려면 transaction.on_commit()
함수를 사용할 수 있습니다. 이 함수를 사용하면 트랜잭션 이 데이터베이스 에 커밋된 후 실행 콜백을 등록할 수 있습니다. 함수 또는 호출 가능한 객체 를 인수로 on_commit()
에 전달합니다.
다음 예시 관련 데이터베이스 트랜잭션 완료된 후에만 genre
값이 ["Horror", "Comedy"]
인 영화를 쿼리합니다.
def get_horror_comedies(): movies = Movie.objects.filter(genres=["Horror", "Comedy"]) for m in movies: print(f"Title: {m.title}, runtime: {m.runtime}") def insert_movie_with_callback(): with transaction.atomic(): Movie.objects.create( title="The Substance", runtime=140, genres=["Horror", "Comedy"] ) transaction.on_commit(get_horror_comedies)
트랜잭션 오류 처리
트랜잭션 중에 발생하는 예외를 처리하다 하려면 원자성 코드 차단 주위에 오류 처리 로직을 추가합니다. 원자성 차단 내부의 오류를 처리하다 경우 Django에서 이러한 오류를 가릴 수 있습니다. 장고는 오류를 사용하여 트랜잭션 커밋 할지 아니면 롤백할지 결정하기 때문에 예기치 않은 동작이 발생할 수 있습니다.
트랜잭션 성공하지 못하면 Django는 모델 필드에 대한 변경 사항을 되돌리지 않습니다. 모델과 데이터베이스 문서 간의 불일치를 방지하려면 원래 필드 값을 수동으로 복원 해야 할 수 있습니다.
예시
다음 예시 데이터베이스 트랜잭션 실패할 경우 조회된 문서 의 수정된 title
값을 되돌리는 오류 처리 로직이 포함되어 있습니다.
movie = Movie.objects.get(title="Jurassic Park") movie.title = "Jurassic Park I" try: with transaction.atomic(): movie.save() except DatabaseError: movie.title = "Jurassic Park" if movie.title == "Jurassic Park I": movie.plot = "An industrialist invites experts to visit his theme park of cloned dinosaurs. After a power failure," \ " the creatures run loose, putting everyone's lives, including his grandchildren's, in danger." movie.save()
이 코드는 모델의 title
값에 따라 두 번째 데이터베이스 작업을 수행하므로 트랜잭션 오류가 발생할 경우 변경 사항을 되돌리면 추가 데이터 불일치를 방지할 수 있습니다.