Menu Docs
Página inicial do Docs
/ / /
Driver C++
/

Transações

Nesta página

  • Visão geral
  • APIs de transações
  • API de retorno de chamada
  • Core API
  • Informações adicionais
  • Documentação da API

Neste guia, você pode aprender como usar o Driver MongoDB C++ para executar transações. As transações permitem que você execute uma série de operações que não alteram nenhum dado até que a transação seja confirmada. Se qualquer operação na transação retornar um erro, o driver cancelará a transação e descartará todas as alterações de dados antes que elas se tornem visíveis.

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 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 mongocxx::client. Em seguida, você pode utilizar a instância do mongocxx::client_session resultante para executar transações. Recomendamos que você reutilize seu cliente para várias sessões e transações, em vez de fazer a instância de um novo cliente a cada vez.

Aviso

Use uma mongocxx::client_session somente com o mongocxx::client que a criou. Utilizar uma client_session com um client diferente resulta em erros de operação.

Importante

As instâncias de mongocxx::client não são seguras para thread. Cada mongoxcc::client instância e suas instâncias filhas, incluindo mongocxx::client_session, devem ser usadas por um único thread por vez. Para saber mais, consulte o guia Segurança de threads e forquilhas.

O driver C++ do MongoDB fornece uma API de chamada de resposta de chamada e uma API principal para gerenciar o estilo de vida da transação. Antes de iniciar uma transação, você deve chamar o método start_session() para instanciar um mongocxx::client_session. Em seguida, você pode usar uma das seguintes APIs para realizar uma transação:

  • API de chamada de resposta: API de alto nível que gerencia o ciclo de vida da transação e incorpora automaticamente a lógica de tratamento de erros.

  • API central: API de baixo nível que permite gerenciar o ciclo de vida da transação e implementar lógica personalizada de tratamento de erros.

Dica

Para saber mais sobre o tratamento de erros, consulte a seção Tratamento de erros de transação no manual do MongoDB Server .

Use a API de chamada de resposta de resposta para permitir que o driver C++ do MongoDB gerencie o ciclo de vida de sua transação. Para implementar essa API, chame o método with_transaction() no seu mongocxx::client_session e passe uma função de chamada de resposta de chamada especificando a sequência de operações que você deseja executar. O método with_transaction() inicia uma transação, executa a função de chamada de resposta de resposta e confirma sua transação ou encerra a transação se encontrar um erro. Se sua transação encontrar um erro TransientTransactionError ou UnknownTransactionCommitResult, o método with_transaction() executará novamente a transação.

O código a seguir usa a API de chamada de resposta de resposta para executar uma transação que insere documentos nas coleção movies e comments no banco de banco de dados sample_mflix . Este código executa as seguintes ações:

  1. Inicia uma sessão a partir do cliente utilizando o método start_session().

  2. Define uma função de chamada de resposta de chamada que especifica as operações a serem executadas durante a transação.

  3. Cria um objeto de opção para se preparar para definir a preocupação de gravação para as operações de transação. Para saber mais sobre semântica de leitura e escrita, consulte a seção Read Concern/Write Concern/Read Preference no manual do MongoDB Server .

  4. Chama o método with_transaction() para gerenciar a transação, passando a função de chamada de resposta de resposta e o objeto de opção como argumentos.

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define a callback specifying the sequence of operations to perform during the transaction
mongocxx::client_session::with_transaction_cb callback = [&](mongocxx::client_session* session) {
// Important:: You must pass the session to the operations.
movies_collection.insert_one(*session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(*session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
};
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
// Start a client session
auto session = client.start_session();
try {
// Start a transaction, execute the operations in the callback function, and commit the results
session.with_transaction(callback, opts);
} catch (const mongocxx::exception& e) {
std::cout << "An exception occurred: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;

Use a API principal para gerenciar o ciclo de vida de sua transação. Para implementar essa API, você deve fazer chamadas explícitas para métodos na interface mongocxx::client_session para iniciar uma transação, confirmar uma transação ativa e encerrar uma transação se ocorrer um erro. A API principal não incorpora automaticamente a lógica de tratamento de erros e, em vez disso, permite que você implemente a lógica de tratamento personalizada para erros, incluindo TransientTransactionError e UnknownTransactionCommitResult.

A tabela a seguir descreve os principais métodos de API fornecidos pela interface mongocxx::client_session :

Método
Descrição

start_transaction()

Starts a new transaction on the current client session. Accepts an optional mongocxx::options::transaction instance as an argument to set options. For a full list of options, see mongocxx::options::transaction in the API documentation.

Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with a transaction already in progress. If an error is returned with the TransientTransactionError label, you can end the transaction and then retry it with the expectation that it will succeed.

To learn more about this method, see the startTransaction() guide in the MongoDB Server manual.

commit_transaction()

Commits the active transaction on the current client session.

Raises an exception if options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with no transaction in progress. If an error is returned with the UnknownTransactionCommitResult label, you can end the transaction and then retry it with the expectation that it will succeed when the committed transaction satisfies the set write concern.

To learn more about this method, see the commitTransaction() guide in the MongoDB Server manual.

abort_transaction()

Ends the active transaction on the current client session.

Raises an exception if the options are misconfigured or if there are other errors such as a session with no transaction in progress.

To learn more about this method, see the abortTransaction() guide in the MongoDB Server manual.

Dica

A mongocxx::client_session classe também fornece métodos para recuperar e modificar propriedades da sessão. Para saber mais, consulte mongocxx::client_session na documentação da API.

O código a seguir usa a API principal para executar uma transação que insere documentos nas coleções movies e comments no banco de banco de dados sample_mflix . Este código executa as seguintes ações:

  1. Inicia uma sessão a partir do cliente utilizando o método start_session().

  2. Cria um objeto de opção para se preparar para definir a preocupação de gravação para as operações de transação. Para saber mais sobre semântica de leitura e escrita, consulte a seção Read Concern/Write Concern/Read Preference no manual do MongoDB Server .

  3. Chama o método start_transaction() para iniciar uma transação, passando o objeto de opção como um argumento.

  4. Executa operações para inserir documentos em collections no banco de banco de dados sample_mflix, passando a sessão ativa para cada operação. Se uma operação encontrar um erro, toda a transação será abortada. Se o erro tiver o rótulo TransientTransactionError, a transação será tentada novamente.

  5. Confirma a transação ativa usando o método commit_transaction(). Se a confirmação encontrar um erro com o rótulo UnknownTransactionCommitResult, a confirmação será repetida.

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Runs the txn_func and retries if TransientTransactionError occurs
using transaction_func = std::function<void(mongocxx::client_session& session)>;
auto run_with_retry = [](transaction_func txn_func,
mongocxx::client_session& session) {
while (true) {
try {
txn_func(session); // performs transaction.
break;
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Transaction aborted. Caught exception during transaction."
<< std::endl;
// If transient error, retry the whole transaction.
if (oe.has_error_label("TransientTransactionError")) {
std::cout << "TransientTransactionError, retrying transaction..."
<< std::endl;
continue;
} else {
throw oe;
}
}
}
};
// Commits the active transaction and retries commit if UnknownTransactionCommitResult occurs
auto commit_with_retry = [](mongocxx::client_session& session) {
while (true) {
try {
session.commit_transaction(); // Uses write concern set at transaction start.
std::cout << "Transaction committed."
<< std::endl;
break;
} catch (const mongocxx::operation_exception& oe) {
// Can retry commit
if (oe.has_error_label("UnknownTransactionCommitResult")) {
std::cout << "UnknownTransactionCommitResult, retrying commit..."
<< std::endl;
continue;
} else {
std::cout << "Error during commit..."
<< std::endl;
throw oe;
}
}
}
};
auto txn_func = [&](mongocxx::client_session& session) {
auto& client = session.client();
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
session.start_transaction(opts);
// Attempt to insert documents into database collections
try {
movies_collection.insert_one(session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Caught exception during transaction, aborting."
<< std::endl;
session.abort_transaction();
throw oe;
}
commit_with_retry(session);
};
// Start a client session
auto session = client.start_session();
try {
run_with_retry(txn_func, session);
} catch (const mongocxx::operation_exception& oe) {
// Do something with error
throw oe;
}

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

Para saber mais sobre a conformidade do ACID , consulte o guia Propriedades do ACID em sistemas de gerenciamento de banco de dados no site do MongoDB .

Para saber mais sobre operações de inserção, consulte o guia Inserir documento .

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

Voltar

GridFS