Use a Convenient Transaction API
Nesta página
Você pode executar uma transação para executar uma série de operações que não alteram nenhum dado até que toda a transação seja confirmada. Este exemplo de uso usa a Convenient Transaction API para executar uma transação.
Dica
Veja também:
Para saber mais sobre as transações que são executadas no driver Node.js , consulte o guia detransações .
O driver do Node.js também fornece a Core API para executar transação. Para saber mais sobre a Core API, consulte o exemplo Usar a Core API .
Exemplo
Considere a situação em que um cliente compra itens de sua loja. Para registrar a compra, seu aplicativo deve atualizar seu estoque e registrar as informações do pedido.
A tabela a seguir descreve as collection que armazenam dados de compra e como uma compra altera os dados em cada collection.
collection | (operação) | Descrição da alteração |
---|---|---|
orders | insert | Insere um documento que descreve o pedido |
inventory | update | Atualiza as quantidades de itens disponíveis após uma compra |
Dados de amostra
A coleção inventory
contém os seguintes documentos:
{ item: "sunblock", qty: 85, price: 6.0 }, { item: "beach chair", qty: 30, price: 25.0 }
Você armazena registros de compra na collection orders
do reconhecimento de data center testdb
. Esta collection está vazia, pois não houve compras.
Implementação
O exemplo de código nesta seção demonstra como usar a Convenient Transaction API para realizar uma transação de vários documentos em uma sessão. Neste exemplo, a transação faz as alterações necessárias quando um cliente compra itens da sua loja.
Este código de exemplo executa uma transação por meio da seguinte ação:
Chama o método
withSession()
no cliente para criar implicitamente a sessão e executar a chamada de resposta passada para ele dentro da sessão.Chama o método
withTransaction()
na sessão para criar uma transação, executar o retorno de chamada passado para ele e confirmar a transação. Se a transação falhar, este método encerra a transação e retorna uma mensagem de erro.Executa as seguintes operações dentro da transação:
Atualiza a collection
inventory
eorders
se houver estoque suficiente para atender à compraEncerra a transação e lança uma exceção se não houver estoque suficiente para qualquer item no pedido
Retorna uma mensagem reconhecendo que a transação foi confirmada com sucesso com uma cópia do registro de compra
Imprime o tipo de retorno de
withSession()
, que é a mensagem de erro ou o reconhecimento de que a transação foi concluída.
const txnResult = await client.withSession(async (session) => session .withTransaction(async (session) => { const invColl = client.db("testdb").collection("inventory"); const recColl = client.db("testdb").collection("orders"); let total = 0; for (const item of order) { /* Update the inventory for the purchased items. End the transaction if the quantity of an item in the inventory is insufficient to complete the purchase. */ const inStock = await invColl.findOneAndUpdate( { item: item.item, qty: { $gte: item.qty }, }, { $inc: { qty: -item.qty } }, { session } ); if (inStock === null) { await session.abortTransaction(); return "Item not found or insufficient quantity."; } const subTotal = item.qty * inStock.price; total = total + subTotal; } // Create a record of the purchase const receipt = { date: new Date(), items: order, total: total, }; await recColl.insertOne(receipt, { session }); return ( "Order successfully completed and recorded!\nReceipt:\n" + JSON.stringify(receipt, null, 1) ); }, null) .finally(async () => await client.close()) ); console.log(txnResult);
Exemplos de pedidos e resultados de transação
Esta seção descreve os resultados da transação realizadas para duas solicitações de amostra.
Existe estoque suficiente para o seguinte pedido, então a transação é concluída com sucesso:
{ item: "sunblock", qty: 3 }, { item: "beach chair", qty: 1 }
Depois de passar esse pedido para o código de transação do exemplo, o código gera o seguinte resultado:
Order successfully completed and recorded! Receipt: { "date": "2023-08-25T20:06:52.564Z", "items": [ { "item": "sunblock", "qty": 3 }, { "item": "beach chair", "qty": 1 } ], "total": 43, "_id": "..." }
Na collection inventory
, a quantidade de "sunblock"
agora é 82
e a quantidade de "beach chair"
é 29
. A collection orders
contém o registro da compra.
Não há estoque suficiente para o seguinte pedido, portanto, o driver encerra a transação:
{ item: "volleyball", qty: 1 }
Depois de passar esse pedido para o código de transação do exemplo, o código gera o seguinte resultado:
Item not found or insufficient quantity.
Como o driver encerra a transação, não há alterações na collection inventory
e orders
.
Documentação da API
Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste exemplo de uso, consulte a seguinte documentação da API: