Fala galera! Há poucos dias um Twitter na conta oficial do projeto Node.js anunciou oficialmente…
Transações com MongoDb (C#) e Tech-Talk JS+5 min read
Categoria: C# Engenharia de Softwares MongoDb
Fala pessoal! Você que trabalha com o MongoDb sabe que ele é um super banco de dados NoSQL orientado a documentos e provavelmente um dos mais completos e fácil de usar, e isso se deve ao fato dele ter drivers que suportam basicamente todas as linguagens modernas de back-end (C#, JAVA, Go, JavaScript [NodeJs]), consultas que usam um formato muito parecido com JSON e o suporte a recursos como transações multi-documentos. Recentemente, tive a oportunidade de apresentar uma talk falando sobre isso e aqui, nesta postagem, compartilho esse conteúdo com vocês.
O Tech-Talk: direto ao ponto
Para quem preferir assistir o tech-talk, segue o vídeo:
Material sobre a apresentação:
- Apresentação
- Github com o projeto de exemplo (o código sobre as transações está no projeto de teste)
Para quem prefere ler, seguimos com o artigo abaixo 😉
Como funcionam as transações no MongoDb
O MongoDb por padrão já trabalha com transações ao nível de documentos (transações atômicas). A partir da versão 4.0 começamos a ter suporte para transações multi-documentos em servidores replica sets e a partir da versão 4.2 em servidores sharded clusters, também. Veja que: em servidores standalone não é suportado transações multi-documentos.
Sobre o funcionamento das transações no MongoDb, considerando que os requisitos acima foram cumpridos, o que se espera é a possibilidade de você manipular de forma atômica várias collections e seus documentos em uma única sessão da transação e de igual modo como acontece com os bancos de dados relacionais, você irá emitir o comando commit para persistir as alterações no banco e se houver falha você poderá emitir um comando abort (roolback) da transação.
Requisitos gerais
Para sintetizar em um único lugar todos os requisitos para se ter o suporte ao uso de transações no MongoDb, vamos ver a lista abaixo:
- Versão do banco de dados:
- 4.0 (somente replicasets)
- 4.2 (suporte completo, replicasets e sharded clusters)
- Driver do C#: 2.9.0 ou superior
- Database e collection devem existir antes de se usar uma transação
Este último ponto é importante se atentar pois, considerando que o MongoDb é um banco NoSQL e com isso os documentos e sua estrutura são flexíveis é de se esperar que criar uma collection dentro de uma transação seria possível, porém isso não é possível.
Cuidados com o uso de transações no MongoDb
Existem alguns cenários que você deve ter cautela ao usar transações no MongoDb, são eles:
- Operações de DDL pendentes e transação em progresso: se você tiver um banco que usa transações e precisa fazer uma alteração estrutural, por exemplo, criar um índice em uma collection, se essa collection estiver dentro de uma transação, essa transação pode ter que ficar em espera até que o índice seja criado. O mesmo pode acontecer se você tiver uma operação que precise do lock no database, mas neste último caso o cenário é um pouco pior, pois você pode ficar com várias transações pendentes no database. Deve-se ter atenção na administração do cluster MongoDb quando se usa transações.
- Transações em progresso e conflito de escrita: 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 tentará modificar posteriormente, a transação será interrompida devido a um conflito de gravação.
- Transações em progresso e leituras obsoletas: a recomendação é evitar leituras no escopo das transações, mas se for necessário faça isso de modo que você use a réplica do seu cluster que é utilizado para leitura (o seu readpreference). Mas saiba que: as operações de leitura dentro de uma transação podem retornar dados obsoletos, ou seja, 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.
Tem transações, posso usar o MongoDb em todos os cenários?
O MongoDb é um banco NoSQL muito completo. Realmente, hoje dá para usar ele em muitos cenários, porém seu escopo deve ser limitado a cenários em que você não terá problemas com dados desestruturados.
Se você precisa garantir a consistência do armazenamento dos seus dados, talvez usar um banco de dados relacional faça mais sentido, pois simular uma estrutura relacional no MongoDb não é correto e mesmo que você consiga, teráa um custo muito grande de controle via código.
Show me the code
Na live do tech-talk eu apresento um pouco de código, mas para facilitar a leitura, vou deixar um bloco de código abaixo que mostra como criar uma transação em uma operação simples de inserção, usando o Mongo C# driver. O código está todo comentado (em inglês, para já deixar público no Github 🙂 ):
Fontes
Allowed CRUD Operations
https://docs.mongodb.com/manual/core/transactions-operations/#crud-operations
Working with MongoDB Transactions with C# and the .NET Framework
https://www.mongodb.com/developer/how-to/transactions-c-dotnet/
Driver Versions
https://docs.mongodb.com/manual/core/transactions-in-applications/#driver-versions
Core API
https://docs.mongodb.com/manual/core/transactions-in-applications/#core-api
Pending DDL Operations and Transactions
https://docs.mongodb.com/manual/core/transactions-production-consideration/#pending-ddl-operations-and-transactions
In-progress Transactions and Write Conflicts
https://docs.mongodb.com/manual/core/transactions-production-consideration/#in-progress-transactions-and-write-conflicts
In-progress Transactions and Stale Reads
https://docs.mongodb.com/manual/core/transactions-production-consideration/#in-progress-transactions-and-stale-reads
Session and Transactions (C# Driver)
https://mongodb.github.io/mongo-csharp-driver/2.9/reference/driver/crud/sessions_and_transactions/#sessions