Gestion des transactions MongoDB. MongoDB Avec la version 4.0, support supplémentaire… | par Deepak Singh | Octobre 2020

Voici comment utiliser Retryable et MongoTemplate pour la transaction MongoDB

Deepak Singh |
MongoDB

La gestion des transactions est un aspect critique de la création d’applications. Voyons comment Mongo DB et ses dernières versions peuvent nous aider à y parvenir.

MongoDB, avec sa version 4.0, a ajouté la prise en charge de la transaction multi-documents qui fonctionne sur les ensembles de répliques. Cette prise en charge a également été étendue à Sharded Cluster avec la version 4.2.

Ce blog peut vous aider

  1. ajoutez la prise en charge des transactions dans votre application à l’aide des pilotes Java Spring Data et Java Mongo, et
  2. avec les bonnes pratiques à suivre

Vous devez avoir une compréhension des frameworks Core-Java, Spring et Spring-Data, et une compréhension de base des requêtes et des concepts Mongo.

MongoDB est une base de données NoSQL et est fondamentalement différente de la modélisation de données SQL en ce qu’elle encourage toujours à avoir des données liées dans un seul document (rappelez-vous que MongoDB fonctionnera mieux si vous l’utilisez correctement; évitez de l’utiliser comme base de données relationnelle). Comme MongoDB prend en charge les transactions ACID dans un seul document, les développeurs d’applications n’ont pas à se soucier des garanties ACID sur plusieurs documents.

Mais parfois, en fonction des besoins et de la conception de votre application, vous ne pouvez pas tout avoir dans un seul document. Vous voudrez peut-être que les documents soient répartis sur plusieurs collections, et de tels scénarios nécessitent des garanties ACID.

Discutons donc de quelques concepts autour de la prise en charge de MongoDB Transaction. Plus tard dans le blog, je partagerai également l’extrait de code qui vous aidera à ajouter un support transactionnel dans votre application.

Plusieurs opérations d’écriture effectuées simultanément sur le même document en dehors de la portée transactionnelle provoquent également WriteConflict. Mais en tant que développeur, vous n’avez pas à vous soucier du problème car WiredTiger gère en interne les erreurs WriteConfilct et continue de réessayer les mises à jour jusqu’à ce qu’il puisse se terminer sans rencontrer de conflits ou dans un MaxTime défini.

MongoDB utilise des mises à jour optimistes pour la concurrence au niveau du document et WriteConflict indique lorsque plusieurs utilisateurs essaient simultanément de mettre à jour le même document.

MongoDB utilise WiredTiger Storage Engine pour gérer ces problèmes. Tout WriteConflict différent de zéro notifie au moteur que les demandes de mise à jour du document peuvent entraîner une violation de concurrence des données. Chaque fois que l’API WiredTiger détecte un WriteConflict en raison d’une violation de concurrence d’accès, elle incrémente les métriques WriteConflict et MongoDB retente les mises à jour en interne jusqu’à ce qu’elle se termine sans rencontrer de conflit.

Un grand nombre de WriteConflict peut entraîner un retard dans la réponse de l’application et vous devrez essayer de trouver la cause.

Comme déjà mentionné, toute mise à jour provoquant des conflits d’écriture en dehors de la transaction est automatiquement réessayée par le moteur de stockage WiredTiger.

L’écriture à l’intérieur de la portée de la transaction fonctionne un peu différemment. Dans WiredTiger, une mise à jour d’un document est optimiste et abandonne la transaction au cas où un conflit serait détecté.

Prenons l’exemple suivant illustré dans le diagramme:

Si une application différente / même tente de modifier le même document avant la fin d’une transaction, elle lèvera une erreur WriteConflict.

Dans le diagramme ci-dessus, vous pouvez voir qu’une transaction (t1) est soumise à WriteConflict car le même document (D1) est modifié simultanément par une autre application avant la fin de la transaction. Peu importe si l’autre opération d’écriture est dans la portée de la transaction ou non.

Exemple d’erreur WriteConflict:

Un comportement d’opération d’écriture dans un cluster fragmenté est similaire à ce qui a été expliqué ci-dessus. Dans un environnement fragmenté, vous pouvez voir une erreur telle que «StaleConflict» qui se produit lors d’une migration de bloc. (Remarque: Chunk Migration sera couvert dans un autre article) Mais, en bref, MongoDB utilise ce mécanisme pour diviser les données et les distribuer uniformément en fonction de la clé Shard.

Les développeurs d’applications doivent avoir une logique pour abandonner la transaction en cours et réessayer pour toutes les exceptions, telles que MVCC (Multiversion Concurrency Control) qui inclut un conflit d’écriture, une panne de réseau transitoire ou une élection de réplica principal.

Si vous utilisez un pilote Mongo-Java principal, la nouvelle API de rappel incorpore une logique de nouvelle tentative pour les erreurs de validation TransientTransactionError ou UnknownTransactionCommitResult.

Voici les extraits de code pour introduire la gestion des transactions-

Pour utiliser Spring-Data Transaction Management, vous devez configurer MongoTransactionManager Bean.

Avec les annotations transactionnelles et réessayables, vous n’avez pas à réessayer vous-même la logique pour gérer la transaction manuellement.

Vous pouvez définir le problème de lecture et d’écriture via MongoClientOption.

La création de transactions de longue durée et l’exécution d’opérations excessives peuvent entraîner une pression élevée sur le cache du moteur de stockage WiredTiger.

La limite de transaction par défaut de MongoDB est de 60 secondes et toute transaction exécutée en dehors de la limite sera abandonnée. Vous avez la possibilité de modifier ce numéro et d’exécuter la transaction plus longtemps.

Pour éviter le problème de délai d’expiration, les transactions doivent être divisées en parties plus petites tout en n’effectuant rien d’autre que les opérations de base de données (évitez d’exécuter une logique d’application / métier dans la transaction).

Les transactions qui affectent plusieurs fragments entraînent des coûts de performances plus élevés car la requête est diffusée sur plusieurs nœuds participants sur le réseau.
Identifiez les requêtes et indiquez une indexation appropriée. Si vous voulez une lecture cohérente dans Distributed multi-shard, utilisez le «snapshot» readConcern. Cela fournit un instantané cohérent de vos données sur plusieurs fragments. Utilisez le niveau readConcern «local» si la latence est un problème pour l’application.

MongoDB vous permet de spécifier le WriteConcern pour définir le niveau de garantie de durabilité lors de l’écriture dans la base de données.

Notez que les problèmes d’écriture s’appliquent à toute opération exécutée sur la base de données, que vous exécutiez une opération régulière sur un seul document ou une transaction multi-document.

Voici les options WriteConcern que vous pouvez configurer par connexion, par base de données, par collection ou même par opération.

Les options sont les suivantes:

Ecrire avec accusé de réception Cela utilisera le problème d’écriture par défaut configuré sur le serveur et attendra l’accusé de réception du serveur.

Vous pouvez passer le w valeur pour définir le comportement de l’accusé de réception d’écriture.

W0: Avec ce souci, l’opération d’écriture n’attendra pas un accusé de réception du serveur. Dans ce cas, les données peuvent être restaurées si la réduction principale avant l’opération d’écriture est répliquée sur secondaire.

W1: Avec ce souci, l’opération d’écriture attendra un accusé de réception du primaire dans le cas d’un jeu de réplicas. Dans ce cas, les données peuvent être restaurées si le décrochage principal est répliqué vers le secondaire avant l’opération d’écriture.

W2: Avec ce souci, l’opération d’écriture attendra un accusé de réception du primaire et de l’un des secondaires.

W3: Avec ce souci, l’opération d’écriture attendra un accusé de réception du primaire et des deux secondaires.

Journal reconnu: Avec ce souci, l’opération d’écriture sera confirmée par le serveur une fois qu’elle est vidée dans le journal sur le primaire. L’opération d’écriture avec cette préoccupation garantit des données durables sur le disque, même si le serveur MongoDB tombe en panne.

Réplique reconnue: Il s’agit d’une option obsolète et l’option préférée est d’utiliser le WriteConcern W2, qui se comporte de la même manière que le problème d’accusé de réception du jeu de réplicas.

Majorité: Avec ce souci, l’opération d’écriture attend la majorité des membres porteurs de données et éligibles du jeu de répliques, et elle ne peut pas être annulée même en cas d’élection primaire. Cette préoccupation garantit également que l’opération d’écriture est enregistrée dans le journal sur une majorité de répliques, y compris primaires.

Si vous êtes un nouveau développeur / un développeur expérimenté utilisant MongoDB dans votre application, découvrez les concepts MongoDB sur le site Web de mongodb-university. Tous les cours sont gratuits!

J’espère que l’article a été utile pour les personnes qui cherchent à ajouter la prise en charge des transactions dans MongoDB avec le framework Spring-data.

Merci d’avoir lu!

https://docs.mongodb.com/manual/reference/write-concern/
https://docs.mongodb.com/manual/core/transactions/
https://www.youtube.com/watch?v=3x_Pf9rQGCo