Je crois que la plupart des gens savent ce qu'est le 2PC (protocole de validation en deux phases) et comment l'utiliser en Java ou la plupart des langages modernes. Fondamentalement, il est utilisé pour s'assurer que les transactions sont en synchronisez lorsque vous avez 2 DB ou plus.
Supposons que j'ai deux bases de données (A et B) utilisant 2PC à deux endroits différents. Avant que A et B ne soient prêts à valider une transaction, les deux bases de données feront rapport au gestionnaire de transactions disant qu'elles sont prêtes à valider. Ainsi, lorsque le gestionnaire de transactions est accusé de réception, il enverra un signal à A et B leur disant d'aller de l'avant.
Voici ma question: disons que A a reçu le signal et a validé la transaction. Une fois que tout est terminé, B est sur le point de faire de même mais quelqu'un débranche le câble d'alimentation, provoquant l'arrêt complet du serveur. Lorsque B sera de nouveau en ligne, que fera B? Et comment B le fait-il?
Rappelez-vous, A est engagé mais B ne l'est pas, et nous utilisons 2PC (donc, la conception de 2PC ne fonctionne plus, n'est-ce pas?)
Sur validation en deux phases
La validation en deux phases ne garantit pas qu'une transaction distribuée ne peut pas échouer, mais elle garantit qu'elle ne peut pas échouer en silence sans que la MT en soit consciente.
Pour que B signale la transaction comme étant prête à être validée, B doit avoir la transaction dans un stockage persistant (c'est-à-dire que B doit pouvoir garantir que la transaction peut être validée en toutes circonstances). Dans cette situation, B a persisté dans la transaction mais le gestionnaire de transactions n'a pas encore reçu de message de B confirmant que B a terminé la validation.
Le gestionnaire de transactions interrogera à nouveau B lorsque B reviendra en ligne et lui demandera de valider la transaction. Si B a déjà validé la transaction, il signalera la transaction comme validée. Si B n'a pas encore validé la transaction, il sera alors validé car il l'a déjà persistée et est donc toujours en mesure de valider la transaction.
Pour que B échoue dans cette situation, il devrait subir une défaillance catastrophique qui a perdu des données ou des entrées de journal. Le gestionnaire de transactions sait toujours que B n'a pas signalé de validation réussie.1
En pratique, si B ne peut plus valider la transaction, cela impliquerait que le désastre qui a supprimé B a causé une perte de données, et B signalerait une erreur lorsque la MT lui demanderait de valider un TxID dont il n'était pas au courant ou ne pensait pas être dans un état d'engagement.
Ainsi, la validation en deux phases n'empêche pas une défaillance catastrophique de se produire, mais elle empêche la défaillance de passer inaperçue. Dans ce scénario, le gestionnaire de transactions signalera une erreur à l'application si B ne peut pas valider.
L'application doit toujours pouvoir se remettre de l'erreur, mais la transaction ne peut pas échouer en silence sans que l'application soit informée de l'état incohérent.
Sémantique
Si un gestionnaire de ressources ou un réseau tombe en panne dans la phase 1, le gestionnaire de transactions détectera une erreur fatale (ne peut pas se connecter au gestionnaire de ressources) et marquera la sous-transaction comme ayant échoué. Lorsque le réseau revient, il abandonne la transaction sur tous les gestionnaires de ressources participants.
Si un gestionnaire de ressources ou un réseau tombe en panne au cours de la phase 2, le gestionnaire de transactions continuera d'interroger le gestionnaire de ressources jusqu'à ce qu'il revienne. Lorsqu'il se reconnecte au gestionnaire de ressources, il indique au RM de valider la transaction. Si le RM renvoie une erreur du type 'Unknown TxID', le TM sera conscient qu'il y a un problème de perte de données dans le RM.
Si la MT tombe en panne dans la phase 1, le client se bloquera jusqu'à ce que la TM revienne, sauf si elle expire ou reçoit une erreur en raison de la connexion réseau interrompue. Dans ce cas, le client est informé de l'erreur et peut soit réessayer, soit lancer lui-même l'abandon.
Si la MT tombe en panne en phase 2, elle bloquera le client jusqu'à ce que la TM revienne. Il a déjà signalé la transaction comme validable et aucune erreur fatale ne devrait être présentée au client, bien qu'elle puisse se bloquer jusqu'à ce que la MT revienne. La MT aura toujours la transaction dans un état non validé et interrogera les RM à valider lorsqu'elle reviendra.
Les événements de perte de données post-validation dans les gestionnaires de ressources ne sont pas gérés par le gestionnaire de transactions et sont fonction de la résilience des RM.
La validation en deux phases ne garantit pas la tolérance aux pannes - voir Paxos pour un exemple de protocole qui traite la tolérance aux pannes - mais elle garantit que l'échec partiel d'une transaction distribuée ne peut pas passer inaperçu.
Je pense que la validation en trois phases est une bien meilleure approche. Malheureusement, je n'ai trouvé personne implémentant une telle technologie.
http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/
Voici les parties essentielles de l'article ci-dessus:
La difficulté fondamentale avec 2PC est que, une fois que la décision de s'engager a été prise par le coordinateur et communiquée à certaines répliques, les répliques vont de l'avant et agissent conformément à la déclaration de validation sans vérifier si toutes les autres répliques ont reçu le message. Ensuite, si une réplique qui s'est écrasée se bloque avec le coordinateur, le système n'a aucun moyen de dire quel a été le résultat de la transaction (puisque seuls le coordinateur et la réplique ayant obtenu le message sont sûrs). Étant donné que la transaction a peut-être déjà été validée sur la réplique bloquée, le protocole ne peut pas être interrompu de manière pessimiste, car la transaction peut avoir eu des effets secondaires impossibles à annuler. De même, le protocole ne peut forcer de manière optimiste la transaction à s'engager, car le vote initial aurait pu être abandonné.
Ce problème est - principalement - contourné par l'ajout d'une phase supplémentaire à 2PC, ce qui nous donne sans surprise un protocole de validation en trois phases. L'idée est très simple. Nous divisons la deuxième phase de 2PC - "commit" - en deux sous-phases. Le premier est la phase de "préparation à l’engagement". Le coordinateur envoie ce message à toutes les répliques lorsqu'il a obtenu un vote unanime de "oui" au cours de la première phase. À la réception de ces messages, les répliques entrent dans un état où elles sont en mesure de valider la transaction - en prenant les verrous nécessaires et ainsi de suite - mais ne font absolument aucun travail qu'elles ne peuvent plus annuler. Ils répondent ensuite au coordinateur en lui disant que le message "se préparer à s'engager" a été reçu.
Le but de cette phase est de communiquer le résultat du vote à chaque réplique afin que l'état du protocole puisse être récupéré quelle que soit la réplique morte.
La dernière phase du protocole fait presque exactement la même chose que la phase initiale de "validation ou abandon" dans 2PC. Si le coordinateur reçoit la confirmation de la livraison du message "Préparez-vous à valider" de toutes les répliques, il est alors sûr de poursuivre la validation de la transaction. Cependant, si la livraison n'est pas confirmée, le coordinateur ne peut pas garantir que l'état du protocole sera récupéré en cas de panne (si vous tolérez un nombre fixe de pannes, le coordinateur peut continuer une fois qu'il a reçu f + 1 confirmations). Dans ce cas, le coordinateur annulera la transaction.
Si le coordinateur tombe en panne à tout moment, un nœud de récupération peut prendre en charge la transaction et interroger l'état à partir de toutes les répliques restantes. Si une réplique qui a validé la transaction est tombée en panne, nous savons que chaque autre réplique a reçu un message "se préparer à valider" (sinon le coordinateur ne serait pas passé à la phase de validation), et donc le nœud de récupération sera en mesure de déterminer que la transaction a pu être engagée et de mener le protocole en toute sécurité jusqu'à sa conclusion. Si un réplica signale au nœud de récupération qu'il n'a pas reçu de `` préparation à la validation '', le nœud de récupération saura que la transaction n'a été validée sur aucun réplica et pourra donc soit abandonner de manière pessimiste, soit réexécuter le protocole. Depuis le début.
Est-ce que 3PC résout tous nos problèmes? Pas tout à fait, mais ça se rapproche. Dans le cas d'une partition réseau, les roues se détachent plutôt - imaginez que toutes les répliques qui ont reçu "se préparent à s'engager" se trouvent d'un côté de la partition et celles qui ne l'ont pas été de l'autre. Ensuite, les deux partitions continueront avec des nœuds de récupération qui valideront ou abandonneront respectivement la transaction, et lorsque le réseau fusionnera, le système aura un état incohérent. Donc, 3PC a des exécutions potentiellement dangereuses, tout comme 2PC, mais progressera toujours et satisfera donc ses propriétés de vivacité. Le fait que 3PC ne bloque pas les défaillances d'un nœud unique le rend beaucoup plus attrayant pour les services où la haute disponibilité est plus importante que les faibles latences.
Votre scénario n'est pas le seul où les choses peuvent finalement mal tourner malgré tous les efforts. Supposons que A et B aient tous deux déclaré "prêt à s'engager" dans TM, puis quelqu'un débranche la ligne entre TM et, disons, B. B attend le feu vert (ou non) de TM, mais il a certainement gagné ne pas attendre indéfiniment jusqu'à ce que TM se reconnecte (ses propres ressources impliquées dans la transaction doivent rester verrouillées/inaccessibles pendant tout le temps d'attente pour des raisons évidentes). Ainsi, lorsque B attend trop longtemps pour son propre goût, il prend ce qu'on appelle des "décisions heuristiques". Autrement dit, il décidera de valider ou d'annuler indépendamment de TM, sur la base, eh bien, je ne sais pas vraiment quoi, mais cela n'a pas vraiment d'importance. Il doit être évident que de telles décisions heuristiques peuvent s'écarter de la décision de validation réelle prise par TM.