Twee applicatieservers in twee regio's, één client die via een VPN schrijft, en een vraag die niemand opschreef: welke component beslist dat de schrijfactie heeft plaatsgevonden? Routing brengt het verzoek naar een proces. Een transactiegrens beslist wanneer de wijziging duurzaam en zichtbaar wordt. Dat zijn verschillende taken die door verschillende systemen worden uitgevoerd, en de kloof daartussen is waar de meeste fouten bij schrijven over regio's leven.

Begin bij de bedrijfsregel, niet bij de kaart

Begin met een zin over de bedrijfsregel in plaats van over de geografie: welke lees- en schrijfacties moeten samen slagen, en welke gelijktijdige wijzigingen moeten onmogelijk zijn terwijl dat gebeurt. Voor een voorraadreservering betekent dat dat de voorraadcontrole en de reservering of beide van kracht worden of geen van beide, en dat geen tweede order ondertussen dezelfde eenheid mag verbruiken.

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

Precies die middelste regel slaan teams over. Atomiciteit zonder voldoende isolatie laat twee transacties elk correct committen en toch een toestand produceren die het bedrijf onmogelijk acht, en geen enkele hoeveelheid herhalingslogica repareert dat achteraf.

Eén gezaghebbende grens verslaat twee regionale servers

Regionale applicatieservers kunnen blijven waar ze zijn, zolang ze de operatie indienen bij een dienst die haar binnen één ondersteunde transactiegrens uitvoert. De applicatielaag wordt een router van bedoeling; de datalaag bezit de waarheid.

Houd die grens kort en dicht bij de gegevens die ze raakt. Een transactie die open wordt gehouden terwijl een mens een prompt beantwoordt, of terwijl een aanroep twee regio's doorkruist, besteedt haar tijd aan het vasthouden van vergrendelingen en vergroot de kans dat iets anders erachter in een time-out loopt. Die fout lijkt op een databaseprobleem en is in werkelijkheid een ontwerpprobleem dat zich als zodanig heeft verkleed. De beslissing naar de datalaag verplaatsen verwijdert het meestal volledig.

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;

Lees die schets als een grens, niet als een prestatieadvies. Het punt is dat de controle en het invoegen één commit delen, zodat een gelijktijdige order de voorraad ofwel verbruikt ziet of haar helemaal niet ziet.

Wat een gerepliceerde database wel en niet geeft

Een gerepliceerde database kan een bredere grens bieden wanneer haar eigen transactiemodel dat ondersteunt. Spanner documenteert atomaire lees-schrijftransacties binnen één database over tabellen heen, met gedefinieerde isolatie en herhalingsgedrag. Dat is een garantie die je leest, test en bewust vertrouwt.

Het is ook een garantie die van het product komt, niet van de route. Een VPN tussen regio's verandert hoe pakketten reizen en hoe fouten zich voordoen. Hij verlengt een transactiegrens niet met één rij, hoe gezond de tunnel er ook uitziet. De twee verwarren levert architecturen op waarin elke component haar eigen controle doorstaat en de gegevens het toch niet met elkaar eens zijn.

Twee databases worden geen één systeem

Twee onafhankelijk beheerde databases krijgen geen gedeelde transactiemanager omdat clients beide kunnen bereiken. Als het bedrijf echt een atomaire toezegging over het paar nodig heeft, moeten het coördinatiemechanisme, de deelnemers en het herstelproces allemaal worden gekozen en gekwalificeerd in plaats van aangenomen.

Denk aan het moment waarop een deelnemer of een verbinding verdwijnt nadat het werk is voorbereid. Een ondersteunde gedistribueerde commit kan een onzekere toestand achterlaten die een herstelprocedure en een menselijke beslissing vereist, en hij komt zonder de belofte dat elke regio door elke partitie heen beschrijfbaar blijft.

Als asynchrone coördinatie in plaats daarvan aanvaardbaar is, zeg dat dan expliciet en schrijf de tussenliggende bedrijfstoestanden plus de verzoeningsregels op. Een keten van lokaal gecommitte stappen met compensatie is een legitiem ontwerp; het is alleen geen enkele atomaire transactie onder een andere naam.

Ontwerp de herhaling vóór de eerste storing

Een client kan de respons verliezen nadat de operatie is gecommit, dus de aanroeper kan een time-out niet als een fout behandelen. Bewaar een duurzame verzoekidentiteit en gebruik de uitkomst van de dienst of een idempotentiemechanisme voordat je een wijziging opnieuw probeert, anders wordt de herhaling een tweede schrijfactie.

Automatische transactie-callbacks kunnen ook meer dan eens lopen na een herhaalbare afbreking, wat ze een slechte plek maakt voor onomkeerbare externe effecten. Houd die buiten de callback, tenzij de workflow er een expliciet veilig protocol voor definieert. Dezelfde voorzichtigheid geldt voor alles wat geld kost of een bericht verstuurt. Een dubbele afschrijving is een veel moeilijker gesprek dan een dubbele logregel.

Acceptatie zou vier scenario's moeten naspelen: twee clients die om dezelfde rij strijden, een afbreking waarvan de dienst zegt dat ze herhaalbaar is, een commit waarvan het antwoord nooit aankomt, en het verlies van een regio of van de verbinding daartussen. Leg het gecommitte bedrijfsresultaat en de onopgeloste toestanden naast het routingontwerp vast, zodat niemand het netwerk aanziet voor de component die de garantie levert.

Gerelateerde artikelen