Menu Docs
Página inicial do Docs
/ /

Transações

Neste guia, você pode aprender a usar o driver C 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 alguma operação na transação não for bem-sucedida, a biblioteca interromperá a transação e descartará todas as alterações de 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ê pretende 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. O MongoDB garante que os dados envolvidos em suas operações de transação permaneçam consistentes, mesmo que as operações encontrem erros inesperados.

Ao utilizar o driver C, você pode criar uma nova sessão a partir de uma instância do mongoc_client_t. Em seguida, você pode utilizar a instância do mongoc_client_session_t resultante para executar transações.

Aviso

Utilize uma mongoc_client_session_t apenas com o mongoc_client_t (ou mongoc_database_t ou mongoc_collection_t associada) que a criou. Utilizar uma mongoc_client_session_t com um mongoc_client_t diferente resulta em erros de operação.

O MongoDB permite consistência causal em determinadas sessões de cliente. O modelo de consistência causal garante que, em um sistema distribuído, as operações dentro de uma sessão sejam executadas em uma ordem causal. Os clientes observam resultados consistentes com as relações causais ou as dependências entre as operações. Por exemplo, se você executar uma série de operações em que uma operação depende logicamente do resultado de outra, todas as leituras subsequentes refletirão o relacionamento de dependência .

Para garantir a consistência causal, as sessões de cliente devem atender aos seguintes requisitos:

  • Ao iniciar uma sessão, o driver deve habilitar a opção de consistência causal. Esta opção está habilitada por padrão.

  • As operações devem ser executadas em uma única sessão em um único thread. Caso contrário, as sessões ou threads devem comunicar os valores de optime e tempo de cluster uns aos outros. Para visualizar um exemplo de duas sessões que comunicam estes valores, consulte os exemplos de Consistência causal no manual do MongoDB Server.

  • Você deve usar uma preocupação de leitura MONGOC_READ_CONCERN_LEVEL_MAJORITY .

  • Você deve usar uma preocupação de gravação MONGOC_WRITE_CONCERN_W_MAJORITY . Este é o valor padrão de preocupação de gravação .

A tabela a seguir descreve as garantias que as sessões causalmente consistentes oferecem:

Garantia
Descrição

Ler suas gravações

As operações de leitura refletem os resultados das operações de gravação anteriores.

Leituras monotônicas

As operações de leitura não retornam resultados que reflitam um estado de dados anterior a uma operação de leitura anterior.

Escritas monotônicas

Se uma operação de gravação precisar preceder outras operações de gravação, o servidor executará essa operação de gravação primeiro.

Por exemplo, se você chamar mongoc_collection_insert_one() para inserir um documento e, em seguida, chamar mongoc_collection_update_one() para modificar o documento inserido, o servidor executará a operação de inserção primeiro.

Escritas que seguem as leituras

Se uma operação de gravação precisar seguir outras operações de leitura, o servidor executará primeiro as operações de leitura.

Por exemplo, se você chamar mongoc_collection_find_with_opts() para recuperar um documento e, em seguida, chamar mongoc_collection_delete_one() para excluir o documento recuperado, o servidor executará primeiro a operação de localização.

Dica

Para saber mais sobre os conceitos mencionados nesta seção, consulte as seguintes entradas de manual do MongoDB Server :

Nesta seção, você pode aprender sobre as APIs de transação fornecidas pelo driver C. Antes de iniciar uma transação, você deve criar um mongoc_client_session_t utilizando a função mongoc_client_start_session() na sua instância do mongoc_client_t. Em seguida, você pode usar uma das seguintes APIs para realizar uma transação:

O driver C fornece uma Convenient Transaction API para gerenciar o ciclo de vida da transação. Implemente essa API usando a função mongoc_client_session_with_transaction() para executar uma chamada de resposta personalizada em uma transação. A função mongoc_client_session_with_transaction() executa as seguintes tarefas:

  • Inicia a transação

  • Lida com erros encerrando a transação ou tentando novamente, como quando a operação resulta em um TransientTransactionError

  • Confirma a transação

A seção Exemplo de transação deste guia demonstra como usar essa API para realizar uma transação.

Como alternativa, você pode ter mais controle sobre o ciclo de vida da transação usando as seguintes funções com sua instância mongoc_client_session_t:

Função
Descrição

mongoc_client_session_start_transaction()

Starts a new transaction, configured with the given options, on this session. Returns false and sets the provided error if there are invalid arguments, such as a session with a transaction already in progress. To learn more about this function, see the startTransaction() page in the Server manual.

mongoc_client_session_abort_transaction()

Ends the active transaction for this session. Returns false and sets the provided error if there is no active transaction for the session or the transaction has been committed or ended. To learn more about this function, see the abortTransaction() page in the Server manual.

mongoc_client_session_commit_transaction()

Commits the active transaction for this session. Returns an error if there is no active transaction for the session or if the transaction was ended. To learn more about this function, see the commitTransaction() page in the Server manual.

mongoc_client_session_destroy()

Aborts any transactions in progress and ends this session. Frees all client resources associated with this session.

Para saber mais sobre as funções que recuperam mongoc_client_session_t propriedades e modificam propriedades da sessão mutáveis, consulte a documentação da API.

Este exemplo define uma função de chamada de resposta de chamada que modifica os dados nas coleções do banco de banco de dados do sample_bank para uma transação bancária. O código executa as seguintes ações:

  1. Define a função de chamada de resposta de chamada, que recebe a instância mongoc_client_session_t como um parâmetro.

  2. Cria mongoc_collection_t instâncias para acessar as coleções de destino.

  3. Especifica o número da conta e o valor a ser transferido entre contas.

  4. Atualiza os saldos do cliente para refletir a transferência de dinheiro.

  5. Registra um recebimento da transação com um carimbo de data/hora.

  6. Imprime uma mensagem se a transação for confirmada com sucesso.

bool
transaction_callback(mongoc_client_session_t *session, void *ctx, bson_t **reply,
bson_error_t *error)
{
BSON_UNUSED(ctx);
BSON_UNUSED(reply);
mongoc_client_t *client = mongoc_client_session_get_client(session);
mongoc_collection_t *checking = mongoc_client_get_collection(client, "sample_bank", "checking");
mongoc_collection_t *savings = mongoc_client_get_collection(client, "sample_bank", "savings");
mongoc_collection_t *receipts = mongoc_client_get_collection(client, "sample_bank", "receipts");
const char *account_id = "123456";
int transfer_amount = 1000;
bson_t *filter = BCON_NEW("account_id", BCON_UTF8(account_id));
bson_t *update_decrement = BCON_NEW("$inc", "{", "balance", BCON_INT32(-transfer_amount), "}");
bson_t *update_increment = BCON_NEW("$inc", "{", "balance", BCON_INT32(transfer_amount), "}");
if (!mongoc_collection_update_one(checking, filter, update_decrement, NULL, NULL, &error)) {
fprintf(stderr, "Failed to update checking account: %s\n", error.message);
return false;
}
if (!mongoc_collection_update_one(savings, filter, update_increment, NULL, NULL, &error)) {
fprintf(stderr, "Failed to update savings account: %s\n", error.message);
return false;
}
bson_t *receipt = BCON_NEW("account_id", BCON_UTF8(account_id),
"amount", BCON_INT32(transfer_amount),
"timestamp", BCON_DATE_TIME(bson_get_monotonic_time()));
if (!mongoc_collection_insert_one(receipts, receipt, NULL, NULL, &error)) {
fprintf(stderr, "Failed to insert receipt: %s\n", error.message);
return false;
}
mongoc_collection_destroy(checking);
mongoc_collection_destroy(savings);
mongoc_collection_destroy(receipts);
bson_destroy(filter);
bson_destroy(update_decrement);
bson_destroy(update_increment);
bson_destroy(receipt);
printf("Transaction successful!");
return true;
}

Em seguida, execute o seguinte código para executar a transação. Este código conclui as seguintes ações:

  1. Cria uma sessão a partir do cliente utilizando a função mongoc_client_start_session().

  2. Chama a função mongoc_client_session_with_transaction() para gerenciar a transação, passando a sessão e a chamada de resposta de resposta como parâmetros.

mongoc_client_session_t *session = mongoc_client_start_session(client, NULL, NULL);
if (!session) {
fprintf(stderr, "Failed to start session\n");
mongoc_client_destroy(client);
return EXIT_FAILURE;
}
bool result =
mongoc_client_session_with_transaction(session,
(mongoc_client_session_with_transaction_cb_t) transaction_callback,
NULL, NULL, NULL, &error);
if (!result) {
fprintf(stderr, "Transaction error: %s\n", error.message);
}
mongoc_client_session_destroy(session);
mongoc_client_destroy(client);
mongoc_cleanup();
Transaction successful!

Observação

Operações paralelas não suportadas

O driver C não suporta a execução de operações paralelas em uma única transação.

Se você estiver usando o MongoDB Server v8.0 ou posterior, poderá executar operações de gravação em vários namespaces em uma única transação usando operações de gravação em massa. Para obter mais informações, consulte o guiade Operações de gravação em massa.

Para saber mais sobre os conceitos mencionados neste guia, consulte as seguintes páginas no manual do MongoDB Server :

Para saber mais sobre a ACID compliance, consulte Quais são as propriedades ACID nos sistemas de gerenciamento de banco de dados? artigo no site do MongoDB .

Para saber mais sobre qualquer um dos tipos ou funções discutidos neste guia, consulte a seguinte documentação da API:

Voltar

Operações de gravação em massa

Nesta página