En överföring mellan databaser dör när VPN:en fallerar, och „kör det igen“ är ingen återställningsplan. Extraheringen från källan kan vara klar, målet kan redan ha commitat, eller så kan svaret helt enkelt ha förlorats på vägen tillbaka. Dessa tre tillstånd kräver olika åtgärder, och en klient som bara känner till „fel“ kan inte skilja dem åt.

Lösningen är arkitektonisk: ge varje körning en varaktig batch-identitet och låt databaserna svara på frågor i stället för att låta klienten gissa.

Vad databasen faktiskt garanterar

SQL Server och Oracle ger båda atomicitet inuti en transaktion. Ingen av dem ger dig atomicitet över de två. En förlorad anslutning förstör inte databasen och tvingar inte heller fram en manuell rollback, eftersom servern löser sin egen transaktion utan dig. Det som brister är anroparens kunskap om resultatet.

Commitat separat betyder commitat separat. En VPN som bär båda anslutningarna smälter inte samman två commits till en arbetsenhet.

Commiten du aldrig hörde talas om

Ett felmod straffar naiv återförsökslogik: servern committar, och bekräftelsen når aldrig fram till anroparen. Oracle dokumenterar detta som problemet med okänt resultat och erbjuder Transaction Guard för det i transaktionsdokumentationen. Ett kommunikationsfel är inte bevis för att en skickad commit misslyckades, och att behandla det som bevis är sättet en batch publiceras två gånger. Skillnaden är viktigast på återförsöksvägen, där operatören har ett felmeddelande och ingen annan signal att agera på.

Så återställningssteget måste läsa resultatet från målet i stället för att sluta sig till det från feltexten.

Ge överföringen en batch-identitet

Varje körning får ett oföränderligt batch-ID, och målet registrerar vad det gjorde med det ID:t. Livscykeln är fyra steg, och den ser likadan ut oavsett leverantör:

  1. Extrahera en identifierad, oföränderlig källbatch med registrerat schema och gräns.
  2. Överför den till målets stagingområde och upptäck ofullständigt eller motstridigt innehåll innan den förklaras klar.
  3. Tillämpa den enligt målets egna regler för unikhet eller låsning och registrera slutförandet i samma lokala transaktion.
  4. Stäm av det varaktiga resultatet via det stödda protokollet innan du bekräftar eller försöker igen.

Återförsök använder samma ID. Ett nytt ID per försök undergräver duplikatförebyggandet du just byggt, vilket låter självklart tills ett återförsöksomslag genererar ett automatiskt.

ID:t ger dig också något att stämma av mot senare, långt efter att klientprocessen är borta.

Kräv batchen och tillämpa den sedan

Tillämpningssteget måste kräva batch-ID:t, göra affärsändringarna och registrera slutförandet i en lokal transaktion. Att göra kontrollen och infogningen som separata satser återinför det race du försökte ta bort. Om två arbetare tävlar vinner exakt ett krav, och den andra får veta det.

En saknad slutförandepost är inte bevis för att en pågående transaktion aldrig kommer att committa. Kravet måste serialisera konkurrerande försök, eller så måste protokollet läsa det varaktiga resultatet innan något avgörs.

Använd databasens stödda mekanism för den serialiseringen i stället för en kontrollera-och-upprepa-loop i applikationskoden.

Vad designen fortfarande inte kan lova

Staging gör arbetet omstartbart och minskar beroendet av en enda långlivad session. Det skapar inte en enda atomisk commit över SQL Server, Oracle och vilken extern bieffekt jobbet än utför. Om affärsverksamheten verkligen behöver det, designa och kvalificera en stödd distribuerad transaktion eller en avstämningsprocess, inklusive vem som äger arbete med osäkert utfall. Allt svagare än det hör hemma i en avstämnings-runbook, inte i överföringskoden.

Acceptera avbrott på tre ställen: under överföring, under tillämpning och efter commit men före bekräftelse. Kontrollera sedan affärsresultatet i stället för klientens meddelande, och låt batchjournalen säga om arbetet är ofullständigt, commitat eller fortfarande oavklarat.

Relaterade artiklar