MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Uma visão geral das transações ACID de vários documentos no MongoDB e como usá-las

Os sistemas de banco de dados têm um mandato para garantir a consistência e a integridade dos dados, especialmente quando dados críticos estão envolvidos. Esses aspectos são aplicados por meio de transações ACID no MongoDB. Uma transação ACID deve atender a algumas regras definidas para validade de dados antes de fazer qualquer atualização no banco de dados, caso contrário, ela deve ser abortada e nenhuma alteração deve ser feita no banco de dados. Todas as transações do banco de dados são consideradas como uma única operação lógica e durante o tempo de execução o banco de dados é colocado em um estado inconsistente até que as alterações sejam confirmadas. As operações que alteram com êxito o estado do banco de dados são chamadas de transações de gravação, enquanto aquelas que não atualizam o banco de dados, mas apenas recuperam dados, são chamadas de transações somente leitura. ACID é um acrônimo para Atomicidade, Consistência, Isolamento e Durabilidade.

Um banco de dados é um recurso compartilhado que pode ser acessado por diferentes usuários em diferentes momentos ou ao mesmo tempo. Por esse motivo, transações simultâneas podem acontecer e, se não forem bem gerenciadas, podem resultar em travamentos do sistema, falha de hardware, deadlock, desempenho lento do banco de dados ou repetição na execução da mesma transação.

O que são regras ACID?

Todos os sistemas de banco de dados devem atender às propriedades ACID para garantir a integridade dos dados.

Atomicidade

Uma transação é considerada como uma única unidade de operação que pode ser bem-sucedida ou falhar completamente. Uma transação não pode ser executada parcialmente. Se qualquer condição de consulta a uma transação falhar, toda a transação falhará completamente e o banco de dados permanecerá inalterado. Por exemplo, se você deseja transferir fundos da conta X para Y, aqui há duas transações, a primeira é remover fundos de X e a segunda é registrar os fundos em Y. Se a primeira transação falhar, todo o transação será abortada

Consistência

Quando uma operação é emitida, antes da execução, o banco de dados está em um estado consistente e deve permanecer assim após cada transação. Mesmo que haja uma atualização, a transação deve sempre trazer o banco de dados para um estado válido, mantendo as invariantes do banco de dados. Por exemplo, você não pode excluir uma chave primária que foi referenciada como chave estrangeira em outra coleção. Todos os dados devem atender às restrições definidas para evitar corrupção de dados de uma transação ilegal.

Isolamento

Várias transações em execução simultânea são executadas sem afetar umas às outras e seu resultado deve ser o mesmo se elas fossem executadas sequencialmente. Quando duas ou mais transações modificam os mesmos documentos no MongoDB, pode haver um conflito. O banco de dados detectará um conflito imediatamente antes de ser confirmado. A primeira operação para adquirir um bloqueio no documento continuará enquanto a outra falhará e uma mensagem de erro de conflito será apresentada.

Durabilidade

Isso determina que, uma vez que a transação tenha sido confirmada, as alterações devem ser mantidas em todos os momentos, mesmo em caso de falha do sistema, por exemplo, devido a falta de energia ou desconexão da Internet.

Transações de ACID do MongoDB

MongoDB é um banco de dados NoSQL baseado em documentos com um esquema flexível. As transações não são operações que devem ser executadas para cada operação de gravação, pois incorrem em um custo de desempenho maior em relação às gravações de um único documento. Com uma estrutura baseada em documentos e um modelo de dados desnormalizado, haverá uma necessidade minimizada de transações. Como o MongoDB permite a incorporação de documentos, você não precisa necessariamente usar uma transação para atender a uma operação de gravação.

O MongoDB versão 4.0 fornece suporte a transações de vários documentos apenas para implantações de conjuntos de réplicas e provavelmente a versão 4.2 estenderá o suporte para implantações fragmentadas (de acordo com suas notas de lançamento).

Exemplo de uma transação:

Certifique-se de ter uma réplica configurada primeiro. Supondo que você tenha um banco de dados chamado app e uma coleção de usuários no Mongo Shell, execute os seguintes comandos:

$mongos e você deverá ver algo como username:PRIMARY>

$use app

$db.users.insert([{_id:1, name: ‘Brian’}, {_id:2, name: ‘Sheila’}, {_id:3, name: ‘James’}])

Precisamos iniciar uma sessão para nossa transação:

$db.getMongo().startSession() and you should see something like 

session { "id" : UUID("dcfa8de5-627d-3b1c-a890-63c9a355520c") }

Usando esta sessão podemos adicionar mais usuários usando uma transação com os seguintes comandos

$session.startTransaction()

session.getDatabase(‘app’).users.insert({_id:4, name:  ‘Hitler’})

Você será presenteado com WriteResult({“nInsterted”:2})

A transação ainda não foi confirmada e o $db.users.find({}) normal nos dará apenas os usuários salvos anteriormente. Mas se executarmos o

$session.getDatabase(“app”).users.find()

o último registro adicionado estará disponível nos resultados retornados. Para confirmar esta transação, executamos o comando abaixo

$session.commitTransaction()

A modificação da transação é armazenada na memória, por isso, mesmo após a falha, os dados estarão disponíveis na recuperação.

Transações ACID de vários documentos no MongoDB

Essas são operações com várias instruções que precisam ser executadas sequencialmente sem afetar umas às outras. Para o exemplo acima podemos criar duas transações, uma para adicionar um usuário e outra para atualizar um usuário com um campo de idade. Ou seja

$session.startTransaction()

   db.users.insert({_id:6, name “Ibrahim”})

   db.users.updateOne({_id:3 , {$set:{age:50}}})

session.commit_transaction()

As transações podem ser aplicadas a operações em vários documentos contidos em uma ou várias coleções/bancos de dados. Quaisquer alterações devido à transação do documento não afetam o desempenho de cargas de trabalho não relacionadas ou não as exigem. Até que a transação seja confirmada, as gravações não confirmadas não são replicadas para os nós secundários nem são legíveis fora das transações.

Práticas recomendadas para transações do MongoDB

As transações de vários documentos são suportadas apenas no mecanismo de armazenamento WiredTiger. Como mencionado anteriormente, muito poucos aplicativos exigiriam transações e, nesse caso, devemos tentar torná-los curtos. Caso contrário, para uma única transação ACID, se você tentar executar um número excessivo de operações, poderá resultar em alta pressão no cache do WiredTiger. O cache é sempre determinado para manter o estado de todas as gravações subsequentes desde que o instantâneo mais antigo foi criado. Isso significa que novas gravações se acumularão no cache durante toda a transação e serão liberadas somente depois que as transações atualmente em execução em instantâneos antigos forem confirmadas ou anuladas. Para obter o melhor desempenho do banco de dados na transação, os desenvolvedores devem considerar:

  1. Sempre modifique um pequeno número de documentos em uma transação. Caso contrário, você precisará dividir a transação em diferentes partes e processar os documentos em lotes diferentes. No máximo, processe 1.000 documentos por vez.
  2. Exceções temporárias, como aguardar para eleger soluços de rede primários e transitórios, podem resultar no aborto da transação. Os desenvolvedores devem estabelecer uma lógica para repetir a transação se os erros definidos forem apresentados.
  3. Configure a duração ideal para a execução da transação a partir dos 60 segundos padrão fornecidos pelo MongoDB. Além disso, empregue a indexação para permitir acesso rápido aos dados dentro da transação. Você também tem a flexibilidade de ajustar a transação para lidar com os tempos limite, dividindo-a em lotes que permitem sua execução dentro dos limites de tempo.
  4. Decomponha sua transação em um pequeno conjunto de operações para que ela se ajuste às restrições de tamanho de 16 MB. Caso contrário, se a operação juntamente com a descrição do oplog exceder esse limite, a transação será abortada.
  5. Todos os dados relacionados a uma entidade devem ser armazenados em uma estrutura de documento única e rica. Isso é para reduzir o número de documentos que devem ser armazenados em cache quando campos diferentes forem alterados.

Limitações de transações

  1. Você não pode criar ou descartar uma coleção dentro de uma transação.
  2. As transações não podem fazer gravações em uma coleção limitada
  3. As transações levam muito tempo para serem executadas e, de alguma forma, podem diminuir o desempenho do banco de dados.
  4. O tamanho da transação é limitado a 16 MB, exigindo que se divida qualquer um que tenda a exceder esse tamanho em transações menores.
  5. Sujeitar um grande número de documentos a uma transação pode exercer pressão excessiva sobre o mecanismo do WiredTiger e, como ele depende do recurso de instantâneo, haverá uma retenção de grandes operações não liberadas na memória. Isso gera algum custo de desempenho no banco de dados.

Conclusão


O MongoDB versão 4.0 introduziu o suporte a transações de vários documentos para conjuntos de réplicas como um recurso para melhorar a integridade e consistência dos dados. No entanto, existem muito poucos aplicativos que exigiriam transações ao usar o MongoDB. Existem limitações contra esse recurso que o tornam consideravelmente um pouco imaturo no que diz respeito ao conceito de transações. Por exemplo, as transações para um cluster fragmentado não são compatíveis e não podem ser maiores que o limite de tamanho de 16 MB. A modelagem de dados fornece uma estrutura melhor para reduzir as transações em seu banco de dados. A menos que você esteja lidando com casos especiais, será uma prática melhor evitar transações no MongoDB.