Session.commitTransaction()
Nesta página
Definição
Session.commitTransaction()
Salva as alterações feitas pelas operações natransação multidocumento e termina a transação.
Importante
Método mongosh
Esta página documenta um método
mongosh
. Esta não é a documentação de comandos de banco de dados nem drivers específicos de linguagem, como Node.js.Para o comando do banco de dados, consulte o comando
commitTransaction
.Para drivers de API do MongoDB, consulte a documentação do driver do MongoDB específica da linguagem.
Alterado na versão 4.2: A partir do MongoDB 4.2, as transação de vários documento estão disponíveis tanto para clusters fragmentados quanto para conjuntos de réplicas.
Comportamento
Escreva preocupação
Ao confirmar a transação, a sessão utiliza a write concern especificada no início da transação. Consulte Session.startTransaction()
.
Se você confirmar usando a write concern "w: 1"
, sua transação poderá ser revertida durante o processo de failover.
Atomicidade
Quando uma transação é confirmada, todas as alterações de dados feitas na transação são salvas e visíveis fora da transação. Ou seja, uma transação não confirmará algumas de suas alterações enquanto reverte outras.
Até que uma transação seja confirmada, as alterações de dados feitas na transação não serão visíveis fora da transação.
No entanto, quando uma transação é gravada em vários fragmentos, nem todas as operações de leitura externas precisam esperar que o resultado da transação confirmada fique visível nos fragmentos. Por exemplo, se uma transação estiver comprometida e escrever 1 estiver visível no fragmento A, mas escrever 2 ainda não estiver visível no fragmento B, uma leitura externa em questão de leitura "local"
poderá ler os resultados da escrita 1 sem ver a escrita 2.
Repetitivo
Se a operação de confirmação encontrar um erro, os drivers do MongoDB tentarão novamente a operação de confirmação uma única vez, independentemente de retryWrites
estar definido como false
. Para obter mais informações, consulte Tratamento de erros de transação.
Exemplo
Considere um cenário em que, à medida que as alterações são feitas no registro de um funcionário no banco de dados hr
, você deseja garantir que a collection de events
no banco de dados reporting
esteja sincronizada com as alterações hr
. Ou seja, você deseja garantir que essas gravações sejam feitas como uma única transação, de modo que ambas as operações sejam bem-sucedidas ou não.
A collection employees
no banco de dados hr
tem os seguintes documentos:
{ "_id" : ObjectId("5af0776263426f87dd69319a"), "employee" : 3, "name" : { "title" : "Mr.", "name" : "Iba Ochs" }, "status" : "Active", "department" : "ABC" } { "_id" : ObjectId("5af0776263426f87dd693198"), "employee" : 1, "name" : { "title" : "Miss", "name" : "Ann Thrope" }, "status" : "Active", "department" : "ABC" } { "_id" : ObjectId("5af0776263426f87dd693199"), "employee" : 2, "name" : { "title" : "Mrs.", "name" : "Eppie Delta" }, "status" : "Active", "department" : "XYZ" }
A collection events
no banco de dados reporting
tem os seguintes documentos:
{ "_id" : ObjectId("5af07daa051d92f02462644a"), "employee" : 1, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } } { "_id" : ObjectId("5af07daa051d92f02462644b"), "employee" : 2, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "XYZ", "old" : null } } { "_id" : ObjectId("5af07daa051d92f02462644c"), "employee" : 3, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }
O exemplo a seguir abre uma transação, atualiza o status de um funcionário para Inactive
no status employees
, insere um documento correspondente à collection events
e comete as duas operações como uma única transação.
// Runs the txnFunc and retries if TransientTransactionError encountered function runTransactionWithRetry(txnFunc, session) { while (true) { try { txnFunc(session); // performs transaction break; } catch (error) { // If transient error, retry the whole transaction if (error?.errorLabels?.includes("TransientTransactionError") ) { print("TransientTransactionError, retrying transaction ..."); continue; } else { throw error; } } } } // Retries commit if UnknownTransactionCommitResult encountered function commitWithRetry(session) { while (true) { try { session.commitTransaction(); // Uses write concern set at transaction start. print("Transaction committed."); break; } catch (error) { // Can retry commit if (error?.errorLabels?.includes("UnknownTransactionCommitResult") ) { print("UnknownTransactionCommitResult, retrying commit operation ..."); continue; } else { print("Error during commit ..."); throw error; } } } } // Updates two collections in a transactions function updateEmployeeInfo(session) { employeesCollection = session.getDatabase("hr").employees; eventsCollection = session.getDatabase("reporting").events; session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } ); try{ employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } ); eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } ); } catch (error) { print("Caught exception during transaction, aborting."); session.abortTransaction(); throw error; } commitWithRetry(session); } // Start a session. session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); try{ runTransactionWithRetry(updateEmployeeInfo, session); } catch (error) { // Do something with error } finally { session.endSession(); }