Deux serveurs d’application dans deux régions, un client qui écrit à travers un VPN, et une question que personne n’a écrite : quel composant décide que l’écriture a eu lieu ? Le routage amène la requête à un processus. Une frontière de transaction décide quand le changement devient durable et visible. Ce sont des tâches différentes accomplies par des systèmes différents, et l’écart entre elles est là où vivent la plupart des bogues d’écriture multirégion.

Partez de la règle métier, pas de la carte

Partez d’une phrase sur la règle métier plutôt que sur la géographie : quelles lectures et quelles écritures doivent réussir ensemble, et quels changements concurrents doivent être impossibles pendant ce temps. Pour une réservation de stock, cela signifie que la vérification du stock et la réservation soit prennent toutes deux effet, soit aucune, et qu’aucune seconde commande ne peut consommer la même unité entre-temps.

RequirementWhat satisfies itWhat does not
All-or-nothing applicationA transaction inside one owning systemA VPN path between regions
No double spendIsolation strong enough to exclude the conflictAtomicity alone
Survive a region lossReplication the database itself documentsTwo independent databases behind one client

C’est précisément cette ligne du milieu que les équipes sautent. L’atomicité sans isolation suffisante permet à deux transactions de se valider correctement chacune et de produire malgré tout un état que le métier juge impossible, et aucune quantité de logique de nouvelle tentative ne répare cela après coup.

Une frontière faisant autorité bat deux serveurs régionaux

Les serveurs d’application régionaux peuvent rester où ils sont, à condition de soumettre l’opération à un service qui l’exécute à l’intérieur d’une seule frontière de transaction prise en charge. La couche applicative devient un routeur d’intention ; la couche de données possède la vérité.

Gardez cette frontière courte et proche des données qu’elle touche. Une transaction maintenue ouverte pendant qu’un humain répond à une invite, ou pendant qu’un appel traverse deux régions, passe son temps à tenir des verrous et augmente le risque que quelque chose d’autre expire derrière elle. Cette panne ressemble à un problème de base de données et est en réalité un problème de conception qui s’est déguisé en tel. Déplacer la décision dans la couche de données l’élimine généralement tout à fait.

BEGIN;
UPDATE inventory SET reserved = reserved + 1
 WHERE sku = 'A-100' AND available >= 1;
INSERT INTO reservation (sku, order_id) VALUES ('A-100', 'ord-9f');
COMMIT;

Lisez ce schéma comme une frontière, non comme une recommandation de performance. L’idée est que la vérification et l’insertion partagent une même validation, de sorte qu’une commande concurrente voit le stock consommé ou ne le voit jamais.

Ce qu’une base de données répliquée apporte et n’apporte pas

Une base de données répliquée peut fournir une frontière plus large lorsque son propre modèle de transaction le permet. Spanner documente des transactions atomiques de lecture-écriture au sein d’une seule base de données sur plusieurs tables, avec une isolation et un comportement de nouvelle tentative définis. C’est une garantie que l’on lit, que l’on teste et sur laquelle on s’appuie délibérément.

C’est aussi une garantie qui vient du produit, non de la route. Un VPN entre régions change la façon dont les paquets voyagent et dont les pannes se présentent. Il n’étend pas une frontière de transaction d’une seule ligne, aussi sain que le tunnel paraisse. Confondre les deux produit des architectures où chaque composant passe sa propre vérification et où les données ne concordent toujours pas.

Deux bases de données ne deviennent pas un seul système

Deux bases de données gérées indépendamment n’acquièrent pas un gestionnaire de transactions partagé parce que les clients peuvent atteindre l’une et l’autre. Si le métier a réellement besoin d’un engagement atomique sur la paire, le mécanisme de coordination, les participants et le processus de reprise doivent tous être choisis et qualifiés plutôt que supposés.

Pensez au moment où un participant ou un lien disparaît après que le travail a été préparé. Une validation distribuée prise en charge peut laisser un état indécis qui exige une procédure de reprise et une décision humaine, et elle ne promet pas que chaque région reste inscriptible à travers chaque partition.

Si une coordination asynchrone est en revanche acceptable, dites-le explicitement et consignez les états métier intermédiaires ainsi que les règles de réconciliation. Une chaîne d’étapes validées localement avec compensation est une conception légitime ; ce n’est simplement pas une transaction atomique sous un autre nom.

Concevez la nouvelle tentative avant la première panne

Un client peut perdre la réponse après que l’opération a été validée, donc l’appelant ne peut pas traiter un délai d’attente comme un échec. Conservez une identité de requête durable et utilisez le résultat du service ou un mécanisme d’idempotence avant de réessayer une mutation, sinon la nouvelle tentative devient une seconde écriture.

Les rappels automatiques de transaction peuvent aussi s’exécuter plus d’une fois après un abandon réessayable, ce qui en fait un mauvais foyer pour des effets externes irréversibles. Gardez ceux-ci en dehors du rappel, à moins que le flux de travail ne définisse pour eux un protocole sûr explicite. La même prudence vaut pour tout ce qui coûte de l’argent ou envoie un message. Un débit en double est une conversation bien plus difficile qu’une ligne de journal en double.

L’acceptation devrait rejouer quatre scénarios : deux clients en course pour la même ligne, un abandon que le service dit réessayable, une validation dont la réponse n’arrive jamais, et la perte d’une région ou du lien entre elles. Consignez le résultat métier validé et les états non résolus à côté de la conception du routage, afin que personne ne confonde le réseau avec le composant qui fournit la garantie.

Articles similaires