Menu Docs

Página inicial do DocsDesenvolver aplicaçõesDriver PHPLaravel MongoDB

Transações

Nesta página

  • Visão geral
  • Requisitos e limitações
  • Executar uma transação em um retorno de chamada
  • Iniciar e confirmar uma transação
  • Reverter uma transação

Neste guia, você aprenderá a realizar uma transação no MongoDB usando o pacote Laravel MongoDB. As transações permitem que você execute uma sequência de operações de gravação que atualizam os dados somente após a confirmação da transação.

Se a transação falhar, a biblioteca PHP do MongoDB que gerencia as operações do MongoDB para o Laravel MongoDB garante que o MongoDB descarte todas as alterações feitas na transação antes que elas se tornem visíveis. Essa propriedade das transações que garante que todas as alterações em uma transação sejam aplicadas ou descartadas é chamada de atomicidade.

O MongoDB executa operações de gravação em documentos únicos atomicamente. Se você precisar de atomicidade nas operações de gravação em vários documentos ou de consistência de dados em vários documentos para suas operações, execute-as em uma transação multidocumento.

As transações multidocumento estão em conformidade com ACID porque o MongoDB garante que os dados em suas operações de transação permaneçam consistentes, mesmo que o driver encontre erros inesperados.

Saiba como realizar transações nas seguintes seções deste guia:

  • Requisitos e limitações

  • Executar uma transação em um retorno de chamada

  • Iniciar e confirmar uma transação

  • Reverter uma transação

Dica

Para saber mais sobre transações no MongoDB, consulte Transações no manual do servidor.

Para executar transações no MongoDB, você deve usar a seguinte versão e topologia do MongoDB:

  • MongoDB versão 4.0 ou posterior

  • Um sistema de conjunto de réplicas ou cluster fragmentado

O servidor MongoDB e o Laravel MongoDB têm as seguintes limitações:

  • Nas versões 4 do MongoDB .2 e anteriores, as operações de gravação realizadas dentro de uma transação devem estar em coletas existentes. Nas versões 4 do MongoDB .4 e posterior, o servidor cria automaticamente collections conforme necessário quando você executa operações de gravação em uma transação. Para saber mais sobre essa limitação, consulte Criar coleções e índices em uma transação no manual do servidor.

  • O MongoDB não suporta transações aninhadas. Se você tentar iniciar uma transação dentro de outra, a extensão gerará um RuntimeException. Para saber mais sobre essa limitação, consulte Transações e sessões no manual do servidor.

  • O pacote Laravel MongoDB não suporta as características de teste de banco de dados Illuminate\Foundation\Testing\DatabaseTransactions e Illuminate\Foundation\Testing\RefreshDatabase. Como solução alternativa, você pode criar migrações com o traço Illuminate\Foundation\Testing\DatabaseMigrations para redefinir o banco de dados após cada teste.

Esta seção mostra como executar uma transação em uma chamada de resposta.

Ao usar esse método de execução de uma transação, todo o código no método de chamada de resposta é executado como uma única transação.

No exemplo a seguir, a transação consiste em operações de escrita que transferem os recursos de uma conta bancária, representada pelo modelo Account , para outra conta:

DB::transaction(function () {
$transferAmount = 200;
$sender = Account::where('number', 223344)->first();
$sender->balance -= $transferAmount;
$sender->save();
$receiver = Account::where('number', 776655)->first();
$receiver->balance += $transferAmount;
$receiver->save();
});

Opcionalmente, você pode passar o número máximo de vezes para tentar novamente uma transação com falha como o segundo parâmetro, conforme mostrado no exemplo de código a seguir:

DB::transaction(function() {
// transaction code
},
retries: 5,
);

Esta seção mostra como iniciar e confirmar uma transação.

Para usar este método de iniciar e confirmar uma transação, chame o método DB::beginTransaction() para iniciar a transação. Em seguida, chame o método DB::commit() para encerrar a transação, que aplica todas as atualizações realizadas na transação.

No exemplo a seguir, o saldo da primeira conta é movido para a segunda conta, após o que a primeira conta é excluída:

DB::beginTransaction();
$oldAccount = Account::where('number', 223344)->first();
$newAccount = Account::where('number', 776655)->first();
$newAccount->balance += $oldAccount->balance;
$newAccount->save();
$oldAccount->delete();
DB::commit();

Esta seção mostra como reverter uma transação. Um rollback reverte todas as operações de gravação realizadas nessa transação. Isso significa que os dados são revertidos ao seu estado antes da transação.

Para executar a reversão, chame a função DB::rollback() a qualquer momento antes de a transação ser confirmada.

No exemplo a seguir, a transação consiste em operações de gravação que transferem fundos de uma conta, representada pelo modelo Account , para várias outras contas. Se a conta do emissor tiver fundos insuficientes, a transação será revertida e nenhum dos modelos será atualizado:

DB::beginTransaction();
$sender = Account::where('number', 223344)->first();
$receiverA = Account::where('number', 776655)->first();
$receiverB = Account::where('number', 990011)->first();
$amountA = 100;
$amountB = 200;
$sender->balance -= $amountA;
$receiverA->balance += $amountA;
$sender->balance -= $amountB;
$receiverB->balance += $amountB;
if ($sender->balance < 0) {
// insufficient balance, roll back the transaction
DB::rollback();
} else {
DB::commit();
}
← Filas