Menu Docs
Página inicial do Docs
/ / /
Controlador Node.js
/ /

Utilizar a Core API

Nesta página

  • Exemplo
  • Dados de amostra
  • Implementação
  • Resultados da transação
  • Documentação da API

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 Core 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 Convenient Transaction API para executar transação. Para saber mais sobre a API de transação conveniente, consulte o exemplo de uso da API de transação conveniente .

Considere uma situação em que um cliente compra itens da sua loja online. Para registrar a compra, seu aplicativo deve atualizar seu estoque e os pedidos do cliente. Seu aplicativo também precisa salvar os detalhes 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
customers
atualizar ou upsert
Anexa o _id do documento do pedido ao histórico de pedidos no documento do cliente
inventory
update
Atualiza as quantidades de itens disponíveis após uma compra

Os exemplos de código utilizam os seguintes dados de amostra no reconhecimento de data center do testdb :

  • Documentos na coleção customers que descrevem clientes e seus pedidos anteriores

  • Documentos na coleção inventory que incluem quantidades e descrições de todos os itens

O seguinte documento está na collection customers :

{ _id: 98765, orders: [] }

A coleção inventory contém os seguintes documentos:

{ item: "sunblock", item_id: 5432, qty: 85 },
{ item: "beach towel", item_id: 7865, qty: 41 }

Você armazena registros de compra na collection orders do reconhecimento de data center testdb . Esta collection está vazia, pois não houve compras.

Os exemplos de código usam as variáveis cart e payment para representar uma lista de amostra de itens comprados e os detalhes de pagamento do pedido. O seguinte código descreve o conteúdo das variáveis cart e payment :

const cart = [
{ item: 'sunblock', item_id: 5432, qty: 1, price: 5.19 },
{ item: 'beach towel', item_id: 7865, qty: 2, price: 15.99 }
];
const payment = { customer: 98765, total: 37.17 };

O exemplo de código nesta seção demonstra como usar a Core 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:

  1. Chama o método startSession() para criar uma nova sessão

  2. Chama o método startTransaction() com um parâmetro de opções para criar uma nova transação

  3. Executa as seguintes operações dentro da transação:

    • Insere um documento na collection orders que contém informações sobre a compra e o cliente

    • Atualiza a collection inventory se houver estoque suficiente para atender à compra

    • Encerra a transação e lança uma exceção se não houver estoque suficiente para qualquer item no pedido

    • Adiciona a ID do pedido à lista de pedidos anteriores para o cliente

    • Retorna uma mensagem reconhecendo que a transação foi confirmada com sucesso com uma cópia do registro de compra

  4. Chama o método commitTransaction() para confirmar a transação se todas as operações forem concluídas com sucesso

  5. Implementa um bloco catch que contém lógica de tratamento de erros

  6. Chama o método abortTransaction() para encerrar a transação

  7. Chama o método endSession() para encerrar a sessão

async function placeOrder(client, cart, payment) {
const transactionOptions = {
readConcern: { level: 'snapshot' },
writeConcern: { w: 'majority' },
readPreference: 'primary'
};
// Start the session
const session = client.startSession();
try {
// Start the transaction in the session, specifying the transaction options
session.startTransaction(transactionOptions);
const ordersCollection = client.db('testdb').collection('orders');
/* Within the session, insert an order that contains information about the
customer, items purchased, and the total payment */
const orderResult = await ordersCollection.insertOne(
{
customer: payment.customer,
items: cart,
total: payment.total,
},
{ session }
);
const inventoryCollection = client.db('testdb').collection('inventory');
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 inventoryCollection.findOneAndUpdate(
{
item_id: item.item_id,
item_id: { $gte: item.qty }
},
{ $inc: { 'qty': -item.qty }},
{ session }
)
if (inStock === null) {
throw new Error('Insufficient quantity or item ID not found.');
}
}
const customerCollection = client.db('testdb').collection('customers');
// Within the session, add the order details to the "orders" array of the customer document
await customerCollection.updateOne(
{ _id: payment.customer },
{ $push: { orders: orderResult.insertedId }},
{ session }
);
// Commit the transaction to apply all updates performed within it
await session.commitTransaction();
console.log('Transaction successfully committed.');
} catch (error) {
/*
Handle any exceptions thrown during the transaction and end the
transaction. Roll back all the updates performed in the transaction.
*/
if (error instanceof MongoError && error.hasErrorLabel('UnknownTransactionCommitResult')) {
// Add your logic to retry or handle the error
}
else if (error instanceof MongoError && error.hasErrorLabel('TransientTransactionError')) {
// Add your logic to retry or handle the error
} else {
console.log('An error occured in the transaction, performing a data rollback:' + error);
}
await session.abortTransaction();
} finally {
// End the session
await session.endSession();
}
}

Esta seção descreve as alterações de dados criadas pela transação.

A collection customers contém o documento do cliente com um pedido _id anexado ao campo pedidos:

{
"_id": 98765,
"orders": [
"61dc..."
]
}

A collection inventory contém quantidades atualizadas para os itens "sunblock" e "beach towel":

[
{
"_id": ...,
"item": "sunblock",
"item_id": 5432,
"qty": 84
},
{
"_id": ...,
"item": "beach towel",
"item_id": 7865,
"qty": 39
}
]

A collection orders contém as informações do pedido e do pagamento:

[
{
"_id": "...",
"customer": 98765,
"items": [
{
"item": "sunblock",
"item_id": 5432,
"qty": 1,
"price": 5.19
},
{
"item": "beach towel",
"item_id": 7865,
"qty": 2,
"price": 15.99
}
],
"total": 37.17
}
]

Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste exemplo de uso, consulte a seguinte documentação da API:

  • opções de transação

  • ClientSession

  • startSession()

  • startTransaction()

  • commitTransaction()

  • abortTransaction()

  • endSession()

Voltar

Use a Convenient Transaction API