Transações
Nesta página
Visão geral
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.
APIs de transações
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:
Convenient API
O driver C fornece uma Convenient Transaction API para gerenciar o ciclo de vida da transação. Implemente essa API usando a mongoc_client_session_with_transaction()
função para executar uma chamada de resposta de resposta personalizada em uma transação. A mongoc_client_session_with_transaction()
função 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.
Core API
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 |
---|---|
| 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. |
| 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. |
| 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. |
| 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.
Exemplo de transação
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:
Define a função de chamada de resposta de chamada, que recebe a instância
mongoc_client_session_t
como um parâmetro.Cria
mongoc_collection_t
instâncias para acessar as coleções de destino.Especifica o número da conta e o valor a ser transferido entre contas.
Atualiza os saldos do cliente para refletir a transferência de dinheiro.
Registra um recebimento da transação com um carimbo de data/hora.
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:
Cria uma sessão a partir do cliente utilizando a função
mongoc_client_start_session()
.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.
If you're using MongoDB Server v8.0 or later, you can perform write operations on multiple namespaces within a single transaction by using bulk write operations. Para obter mais informações, consulte o guiade Operações de gravação em massa.
Informações adicionais
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 .
Documentação da API
Para saber mais sobre qualquer um dos tipos ou funções discutidos neste guia, consulte a seguinte documentação da API: