TL; DR;
99,9% des développeurs web pensent que l'utilisation correcte d'un SGBDR, avec des transactions, empêche leurs applications de voir des données incorrectes et d'introduire des erreurs graves de qualité des données. Ils ont TOTALEMENT TORT.
J'ai lu avec grand intérêt l'excellent article de Kyle Kingsbury sur le modèle de cohérence de Mongo à l'adresse suivante https://aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads
Évidemment, ce type est très compétent et connaît son sujet. Il fait le travail et tout dans cet article est perspicace et bien organisé.
Ce que j'ai trouvé étonnant, cependant, ce sont les commentaires et ce qu'ils révèlent sur le développeur professionnel moyen :
Les développeurs pensent que l'utilisation d'un SGBDR rend leurs données sûres et ils ont absolument tort
Je ne peux pas vous dire combien de fois je me suis disputé avec des "développeurs professionnels" et surtout des administrateurs système stupides qui croient vraiment que, simplement en disant le mot SGBDR, en faisant tourner un poulet autour de leur tête 3 fois, et en se connectant à la licorne magique des bases de données, leurs données seront en sécurité et à l'abri, vous savez, ... (quelque chose quelque chose à propos de) ... les transactions bancaires et tout ce (non-sens) bavardage sur les transactions et fsync. Et un tas d'autres choses qu'aucun développeur que j'ai rencontré ne comprend vraiment ou n'a considéré dans le contexte d'une application HTTP (indice : sans état).
Avant de continuer, je vais lancer un défi :
- Envoyez-moi votre identifiant GitHub
- Laissez-moi choisir une application basée sur MySQL ou PostgreSQL que vous avez écrite (afin que vous ne puissiez pas la préparer)
- Et je trouverai des chemins de code qui fournissent à la fois des lectures non validées et des lectures sales dans votre application en moins d'un jour
- S'il n'y en a pas, je vous paierai 1000 dollars
- S'il y en a, je pourrai publier n'importe quelle photo de vous que je choisis en annexe de cet article. Photoshop est autorisé.
Trouvez-moi à /contact ou /team/ara-t-howard. Maintenant, continuons...
Devinez, développeur : qu'est-ce qui ne va pas avec ce chemin de code :
@db.transaction do
if no_user_exists_with_conditions?
@user = make_that_user_exists_with_those_conditions!
deliver_an_activation_email_to!(@user)
end
end
Laissez-moi vous révéler quelque chose d'époustouflant :
CE CODE EST COMPLÈTEMENT CASSÉ SUR TOUS LES PRINCIPAUX SGBDR, ET VIRTUELLEMENT TOUTES
LES APPLICATIONS, DANS LE MONDE
Je vous assure que l'email sera envoyé deux fois.
Expliquer les transactions dépasse le cadre de cet article, mais laissez-moi vous présenter les "lectures fantômes"
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Phantom_reads
Dans le code ci-dessus, une 2ème transaction concurrente peut provoquer ce qui suit :
@db.transaction do
if no_user_exists_with_conditions?
# entre-temps, une 2ème transaction a créé un utilisateur en double...
# ce qui suit réussira, dans __les deux__ transactions
@user = make_that_user_exists_with_those_conditions!
# les deux transactions enverront l'email
deliver_an_activation_email_to!(@user)
end
end
# l'une des transactions échouera à valider, et explosera *BOOM* mais, à ce moment-là,
# il est trop tard : l'email a été envoyé deux fois et l'erreur a été commise
Je sais, je sais, vous ne pouvez pas y croire. Mais c'est juste parce que vous ne vous êtes jamais donné la peine de RTFM quand il s'agit de ce que signifie "transaction". Commencez ici :
http://www.postgresql.org/docs/9.1/static/transaction-iso.html
Notez ce petit tableau. Laissez-moi vous le traduire :
-
Parce que vous n'avez pas chaque séquence unique de lecture et écriture enveloppée dans une transaction, et que parfois vous lancez simplement du code contre vos objets ORM directement, vous souffrez de la réalité "effrayante" des "lectures non validées" mentionnées dans l'article
-
Parce que vous vous reposez sur le niveau d'isolation par défaut, vous souffrez à la fois des lectures non répétables et des lectures fantômes. (Savez-vous même ce qu'est l'isolation par défaut pour votre base de données et ce que cela signifie ????)
-
Parce que vous n'avez pas défini votre niveau de transaction sur "sérialisable", vous croyez à tort que votre base de données est rapide et sûre. Vous vous êtes trompé en vous basant sur la base de données pour fournir l'intégrité des données comme une abstraction qui ne nécessite pas de réflexion critique et un code d'application au moins 10 fois meilleur que le vôtre. Vous avez toutes les fonctionnalités effrayantes de l'article de Kyle dans vos applications basées sur SGBDR - et, non seulement vous ne le savez pas, mais vous êtes assez sûr que vos données sont "sûres"
Je vous demande donc quelle est la pire décision d'ingénierie :
-
Choisir un outil basé sur des normes que tout le monde est très confiant de comprendre et de savoir utiliser en toute sécurité mais qui, dans son utilisation courante, ne garantit pratiquement jamais ce que vous croyez qu'il promet et, en outre, a été largement critiqué comme ayant des sémantiques ambiguës et inexactes ?
-
Ou accepter ce qui a toujours été vrai : que par elles-mêmes, les bases de données ne peuvent pas fournir des abstractions qui signifient que des développeurs non extrêmement intelligents ne peuvent pas facilement tout gâcher. Et que l'intégrité des données est un concept spécifique au domaine qui doit être implémenté au niveau de l'application, avec seulement une petite partie de cette intégrité étant aidée par le choix de la base de données.
ps. J'ai travaillé sur des systèmes financiers, en temps réel et à haute disponibilité de grande envergure qui utilisent à la fois Mongo et PostgreSQL. C'est sacrément difficile dans les deux cas.
pss. J'ai essayé de commenter votre blog, Kyle, mais les commentaires explosaient ;-)