Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Menu Docs
Página inicial do Docs
/ / /
Backend do Django MongoDB
/

Transações e Sessões

Neste guia, você pode aprender como usar o Backend do Django MongoDB para executar transações. As transações permitem que você execute uma série de operações que alteram os dados somente se toda a transação estiver confirmada. Se qualquer operação na transação não for bem-sucedida, o Django MongoDB Backend interromperá a transação e descartará todas as alterações nos dados antes que elas se tornem visíveis. Esse recurso é chamado de atomicidade.

No MongoDB, as transações são executadas dentro de sessões lógicas. Uma sessão é um agrupamento de operações de leitura ou escrita relacionadas que você deseja executar sequencialmente. As sessões permitem consistência causal para um grupo de operações e permitem executar operações em uma transação compatível com ACID, que é uma transação que atende a uma expectativa de atomicidade, consistência, isolamento e durabilidade.

A API de transação nativa do Django não é suportada, mas o Django MongoDB Backend fornece uma API de transação personalizada que habilita a mesma funcionalidade. Para executar operações dentro de uma transação, defina-as dentro de um bloco atômico de código. O Django MongoDB Backend gerencia a lógica da sessão internamente, portanto, você não precisa iniciar manualmente uma sessão antes de executar uma transação.

Importante

Limitações de transação

A API de transação do Django MongoDB Backend tem várias limitações. Para visualizar uma lista de limitações, consulte Suporte a Banco de Dados e Coleção no guia Django e Compatibilidade de Funcionalidades MongoDB.

Os exemplos nesta aba usam o modelo Movie, que representa a coleção do sample_mflix.movies a partir dosconjuntos de dados de amostra do Atlas. A classe de modelo Movie tem a seguinte definição:

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

O modelo Movie inclui uma classe Meta interna, que especifica os metadados do modelo, e um método __str__(), que define a representação de string do modelo. Para saber mais sobre esses recursos de modelo, consulte Definir um modelo no guia Criar modelos.

Você pode usar o shell interativo do Python para executar os exemplos de código. Para entrar na shell, execute o seguinte comando no diretório raiz do seu projeto:

python manage.py shell

Depois de inserir o shell do Python, certifique-se de importar os seguintes modelos e módulos:

from <your application name>.models import Movie
from django.utils import timezone
from datetime import datetime

Para saber como criar um aplicação Django que use o modelo Movie e o shell interativo Python para interagir com documentos do MongoDB, acesse o tutorial de Introdução.

Para iniciar uma transação no banco de dados , chame a função django_mongodb_backend.transaction.atomic(). Você pode utilizar esta função como construtor ou gerenciador de contexto.

Certifique-se de importar o módulo transaction usando a seguinte instrução de importação:

from django_mongodb_backend import transaction

Você pode iniciar uma transação de banco de dados adicionando o instalador @transaction.atomic acima da sua função. Este modelador garante a atomicidade de quaisquer operações de banco de dados dentro da função. Se a função for concluída com êxito, as alterações serão cometidas ao MongoDB.

O exemplo a seguir chama o método create() em uma transação, que insere um documento na coleção sample_mflix.movies se a transação for bem-sucedida:

@transaction.atomic
def insert_movie_transaction():
Movie.objects.create(
title="Poor Things",
runtime=141,
genres=["Comedy", "Romance"]
)

Alternativamente, você pode utilizar o gerenciador de contexto do transaction.atomic() para criar um bloco atômico de código. Este exemplo executa a mesma operação que o exemplo anterior, mas usa um gerenciador de contexto para iniciar uma transação:

def insert_movie_transaction():
with transaction.atomic():
Movie.objects.create(
title="Poor Things",
runtime=141,
genres=["Comedy", "Romance"]
)

Para executar determinadas ações somente se uma transação for concluída com êxito, você pode usar a função transaction.on_commit() . Esta função permite a você registrar chamadas de resposta que são executadas após uma transação ser confirmada no banco de dados. Passe uma função ou qualquer objeto chamado como argumento para on_commit().

As seguintes queries de exemplo para filmes que têm um valor genre de ["Horror", "Comedy"] somente após a conclusão de uma transação de banco de dados relacionada:

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)

Para lidar com exceções que ocorrem durante uma transação, adicione lógica de tratamento de erros em torno do bloco de código atômico. Se você lidar com erros dentro do bloco atômico, poderá ocultar esses erros do Django. Como o Django usa erros para determinar se deve confirmar ou reverter uma transação, isso pode causar um comportamento inesperado.

Se uma transação não for bem-sucedida, o Django não reverterá nenhuma alteração feita nos campos de um modelo. Para evitar inconsistências entre seus modelos e documentos do banco de dados , talvez seja necessário restaurar manualmente os valores de campo originais.

O exemplo a seguir inclui lógica de tratamento de erros que reverte o valor de title modificado do documento recuperado se a transação do banco de dados falhar:

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()

Como o código executa uma segunda operação de banco de dados com base no valor de title do modelo, a reversão da alteração em caso de erros de transação evita outras inconsistências de dados.

To learn more about the Django transaction API, see Database Transactions in the Django documentation.

Voltar

Atlas Vector Search

Nesta página