Página inicial do Docs → Desenvolver aplicações → Manual do MongoDB
Considerações de produção
Nesta página
- Disponibilidade
- Compatibilidade de recursos
- Limite de tempo de execução
- Limite de tamanho do Oplog
- Cache do WiredTiger
- Transações e segurança
- Restrição de configuração de fragmento
- Clusters fragmentados e árbitros
- Adquirindo travas
- Operações e Transações DDL Pendentes
- Transações em andamento e conflitos de gravação
- Transações em andamento e leituras obsoletas
- Transações em andamento e migração de chunk
- Leituras Externas Durante a Confirmação
- Erros
- Informações adicionais
A página a seguir lista algumas considerações de produção para a execução de transações. Eles se aplicam se você executa transações em conjuntos de réplicas ou clusters fragmentados. Para executar transações em cluster fragmentado, consulte também Considerações de produção ( cluster fragmentado) para obter considerações adicionais específicas do cluster fragmentado.
Disponibilidade
Na versão 4,0, o MongoDB suporta transações de vários documentos em conjuntos de réplicas.
Na versão 4.2, o MongoDB introduz transações distribuídas, que adiciona suporte para transações de vários documentos em clusters fragmentados e incorpora o suporte existente para transações de vários documentos em conjuntos de réplicas.
Para usar transações em implantações do MongoDB 4.2 (conjuntos de réplica e clusters fragmentados), os clientes devem usar drivers do MongoDB atualizados para MongoDB 4.2.
Observação
Transações distribuídas e transações multidocumentos
A partir do MongoDB 4.2, os dois termos são sinônimos. Transações distribuídas referem-se a transações multidocumentos em clusters fragmentados e conjuntos de réplicas. As transações multidocumentos (seja em clusters fragmentados ou conjuntos de réplicas) também são conhecidas como transações distribuídas a partir do MongoDB 4.2.
Compatibilidade de recursos
Para usar transações, a featureCompatibilityVersion para todos os membros da implantação deve ser pelo menos:
Implantação | Mínimo featureCompatibilityVersion |
---|---|
Conjunto de réplicas | 4.0 |
Cluster fragmentado | 4.2 |
Para verificar o fCV de um membro, conecte-se ao membro e execute o comando:
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
Para mais informações, consulte a página de referência do setFeatureCompatibilityVersion
.
Limite de tempo de execução
Por padrão, uma transação deve ter um tempo de execução inferior a um minuto. Você pode modificar este limite utilizando transactionLifetimeLimitSeconds
para as instâncias do mongod
. Para agrupamentos fragmentados, o parâmetro deve ser modificado para todos os membros do conjunto de réplica de fragmento. As transações que excederem esse limite serão consideradas expiradas e serão abortadas por um processo de limpeza periódico.
Para agrupamentos fragmentados, você também pode especificar um limite do maxTimeMS
no commitTransaction
. Para mais informações, consulte Limite de Tempo de Transações de Clusters Compartilhados.
Limite de tamanho do Oplog
- A partir da versão 4.2,
- O MongoDB cria quantas entradas de oplog forem necessárias para encapsular todas as operações de gravação em uma transação, em vez de uma única entrada para todas as operações de gravação na transação. Isso remove o limite de tamanho total de 16 MB para uma transação imposta pela entrada única do oplog para todas as suas operações de gravação. Embora o limite de tamanho total tenha sido removido, cada entrada do oplog ainda deve estar dentro do limite de tamanho do documento BSON de 16 MB.
- Na versão 4,0,
- O MongoDB cria uma única entrada no oplog (registro de operações) no momento do commit se a transação contiver operações de gravação. Ou seja, as operações individuais nas transações não têm uma entrada de oplog correspondente. Em vez disso, uma única entrada de oplog contém todas as operações de gravação dentro de uma transação. A entrada do oplog da transação deve estar dentro do limite de tamanho do documento BSON de 16 MB.
Cache do WiredTiger
Para evitar que a pressão do cache de armazenamento afete negativamente o desempenho:
Ao abandonar uma transação, interrompa a transação.
Quando você encontra um erro durante a operação individual na transação, cancele e tente novamente a transação.
O transactionLifetimeLimitSeconds
também garante que as transações expiradas sejam abortadas periodicamente para aliviar a pressão do cache de armazenamento.
Observação
Se você tiver uma transação não acordada que cause pressão excessiva no cache WiredTiger, a transação cancelará e retornará um erro de conflito de escrita.
Se uma transação for muito grande para caber no cache WiredTiger, a transação será anulada e retornará um erro TransactionTooLargeForCache
.
Transações e segurança
Se estiver executando com controle de acesso, você deverá ter privilégios para as operações na transação.
Se estiver sendo executado com auditoria, as operações em uma transação abortada ainda serão auditadas. No entanto, não há nenhum evento de auditoria que indique que a transação foi anulada.
Restrição de configuração de fragmento
Não é possível executar transações em um cluster fragmentado que tenha um shard com writeConcernMajorityJournalDefault
definido como false
(como um shard com um membro votante que usa o mecanismo de armazenamento na memória).
Clusters fragmentados e árbitros
As transações cujas operações de gravação abrangem vários fragmentos gerarão o erro e serão abortadas se qualquer operação de transação ler ou gravar em um fragmento que contenha um árbitro.
Adquirindo travas
Por padrão, as transações esperam até 5
milissegundos para adquirir as travas exigidas pelas operações na transação. Se a transação não puder adquirir suas travas necessárias dentro dos 5
milissegundos, a transação será cancelada.
As transações liberam todos os bloqueios ao serem abortadas ou confirmadas.
Dica
Ao criar ou descartar uma coleta imediatamente antes de iniciar uma transação, se a coleta for acessada dentro da transação, emita a operação de criação ou entrega em espera com write concern "majority"
para garantir que a transação possa adquirir os bloqueios necessários.
Tempo limite da solicitação de trava
Você pode usar o parâmetro maxTransactionLockRequestTimeoutMillis
para ajustar quanto tempo as transações esperam para adquirir travas. O aumento de maxTransactionLockRequestTimeoutMillis
permite que as operações nas transações esperem o tempo especificado para adquirir as travas necessárias. Isso pode ajudar a evitar abortos de transações em aquisições simultâneas momentâneas de travas, como operações de metadados de execução rápida. No entanto, isso poderia atrasar o aborto das operações de transação em impasse.
Você também pode usar o tempo limite específico da operação definindo maxTransactionLockRequestTimeoutMillis
como -1
.
Operações e Transações DDL Pendentes
Se uma transação de vários documentos estiver em andamento, novas operações DDL que afetam o(s) mesmo(s) banco(s) de dados ou collection(ões) aguardam atrás da transação. Embora essas operações DDL pendentes existam, novas transações que acessam o(s) mesmo(s) banco(s) de dados ou coleção(ões) que as operações DDL pendentes não podem obter os travas necessárias e serão abortadas após a esperamaxTransactionLockRequestTimeoutMillis
. Além disso, novas operações não transacionais que acessam o(s) mesmo(s) banco(s) de dados ou coleção(ões) serão bloqueadas até que atinjam seu limite maxTimeMS
.
Considere os seguintes cenários:
- Operação DDL que requer uma trava de collection
Enquanto uma transação em andamento executa várias operações CRUD na collection
employees
no banco de dadoshr
, um administrador emite a operação DDLdb.collection.createIndex()
na collectionemployees
.createIndex()
requer uma trava de collection exclusiva na collection.Até que a transação em andamento seja concluída, a operação
createIndex()
deve aguardar para obter a trava. Qualquer nova transação que afete a collectionemployees
e seja iniciada enquanto ocreateIndex()
estiver pendente deve aguardar até quecreateIndex()
seja concluída.A operação DDL
createIndex()
pendente não afeta as transações em outras collections no databasehr
. Por exemplo, uma nova transação nacontractors
collection nohr
banco de dados pode ser iniciada e concluída normalmente.- Operação DDL que requer um bloqueio de banco de dados
Enquanto uma transação em andamento executa várias operações CRUD na collection
employees
no banco de dadoshr
, um administrador emite a operação DDLcollMod
na collectioncontractors
no mesmo banco de dados.collMod
requer uma trava de banco de dados no banco de dadoshr
principal.Até que a transação em andamento seja concluída, a operação
collMod
deve aguardar para obter a trava. Qualquer nova transação que afete o databasehr
ou qualquer uma de suas collections e seja iniciada enquantocollMod
estiver pending deverá aguardar até a completes decollMod
.
Em qualquer um dos cenários, se a operação DDL permanecer pendente por mais de maxTransactionLockRequestTimeoutMillis
, as transações pendentes que aguardam essa operação serão canceladas. Ou seja, o valor de maxTransactionLockRequestTimeoutMillis
deve cobrir pelo menos o tempo necessário para que a transação em andamento e a operação DDL pendente sejam concluídas.
Transações em andamento e conflitos de gravação
Se uma transação estiver em andamento e uma gravação fora da transação modificar um documento que uma operação na transação tente modificar posteriormente, a transação será interrompida devido a um conflito de escrita.
Se uma transação estiver em andamento e tiver usado uma trava para modificar um documento, quando uma gravação fora da transação tentar modificar o mesmo documento, a gravação aguardará até que a transação termine.
Transações em andamento e leituras obsoletas
As operações de leitura dentro de uma transação podem retornar dados antigos, conhecidos como leitura obsoleta. Não é garantido que as operações de leitura dentro de uma transação vejam as gravações realizadas por outras transações confirmadas ou gravações não transacionais. Por exemplo, considere a seguinte sequência:
Uma transação está em andamento.
Uma escrita fora da transação exclui um documento.
Uma operação de leitura dentro da transação pode ler o documento agora excluído, pois a operação usa um instantâneo anterior à operação de gravação.
Para evitar leituras obsoletas dentro de transações para um único documento, você pode usar o método db.collection.findOneAndUpdate()
. O exemplo mongosh
a seguir demonstra como você pode usar o db.collection.findOneAndUpdate()
para usar um bloqueio de escrita e garantir que suas leituras estejam atualizadas:
Use db.collection.findOneAndUpdate()
dentro da transação
employeeDoc = employeesCollection.findOneAndUpdate( { _id: 1, status: "Active" }, { $set: { lockId: ObjectId() } }, { returnNewDocument: true } )
Observe que, dentro da transação, a operação findOneAndUpdate
define um novo campo lockId
. Você pode definir o campo lockId
para qualquer valor, desde que modifique o documento. Ao atualizar o documento, a transação adquire uma trava.
Se uma operação fora da transação tentar modificar o documento antes de confirmar a transação, o MongoDB retornará um erro de conflito de gravação para a operação externa.
Transações em andamento e migração de chunk
A migração de chunk adquire travas de collection exclusivas em alguns estágios.
Se uma transação em andamento tiver um bloqueio em uma collection e uma migração de partes que envolva o início dessa collection, esses estágios de migração deverão aguardar que a transação libere os bloqueios na collection, impactando assim o desempenho das migrações de chunks.
Se uma migração de chunk se intercalar com uma transação (por exemplo, se uma transação for iniciada enquanto uma migração de chunk já estiver em andamento e a migração for concluída antes que a transação trave a collection), a transação será interrompida durante a confirmação e será cancelada.
Dependendo de como as duas operações se intercalam, alguns exemplos de erros incluem (as mensagens de erro foram abreviadas):
an error from cluster data placement change ... migration commit in progress for <namespace>
Cannot find shardId the chunk belonged to at cluster time ...
Dica
Veja também:
Leituras Externas Durante a Confirmação
Durante a confirmação de uma transação, operações de leitura externa podem tentar ler os mesmos documentos que serão modificados pela transação. Se a transação for gravada em vários shards, durante a tentativa de confirmação nos shards:
As leituras externas que usam a read concern
"snapshot"
ou"linearizable"
aguardam até que todas as gravações de uma transação estejam visíveis.As leituras externas que fazem parte de sessões causalmente consistentes (aquelas que incluem afterClusterTime) aguardam até que todas as gravações de uma transação estejam visíveis.
As leituras externas que usam outras read concerns não esperam até que todas as gravações de uma transação estejam visíveis, mas leem a versão anterior à transação dos documentos.
Erros
Uso de drivers MongoDB 4,0
Para usar transações em sistemas do MongoDB 4.2 (conjuntos de réplicas e clusters fragmentados), os clientes devem usar drivers do MongoDB atualizados para o MongoDB 4.2.
Em clusters fragmentados com várias instâncias mongos
, a execução de transações com drivers atualizados para o MongoDB 4.0 (em vez do MongoDB 4.2) falhará e poderá resultar em erros, incluindo:
Observação
Seu driver pode retornar um erro diferente. Consulte a documentação do seu driver para obter detalhes.
Código de erro | Mensagem de erro |
---|---|
251 | cannot continue txnId -1 for session ... with txnId 1 |
50940 | cannot commit with no participants |