Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Använd det här mönstret för att återställa arbete när ett eller flera steg misslyckas i en operation som slutligen är konsekvent. Molnbaserade program som implementerar komplexa affärsprocesser och arbetsflöden använder ofta åtgärder som följer den slutliga konsekvensmodellen.
Kontext och problem
Molnprogram ändrar ofta data som är spridda över olika datakällor på olika geografiska platser. För att undvika konkurrens och förbättra prestanda i en distribuerad miljö bör program implementera slutlig konsekvens i stället för stark transaktionskonsekvens. I den slutliga konsekvensmodellen består en typisk affärsåtgärd av en serie separata steg. Under de här stegen kan den övergripande vyn av systemtillståndet vara inkonsekvent. Men systemet bör bli konsekvent igen när alla steg är klara.
Hantering av stegfel utgör en viktig utmaning i den eventuella konsistensmodellen. Efter ett fel kan du behöva ångra arbete från slutförda åtgärdssteg. Du kan dock inte alltid återställa data eftersom andra samtidiga programinstanser kan ändra data. Även om samtidiga instanser inte ändrar data kan det vara mer komplext att ångra ett steg än att återställa det ursprungliga tillståndet. Du kan behöva tillämpa affärsspecifika regler. Ett exempel finns i exemplet med resewebbplatsen.
När en operation som implementerar eventuell konsistens omfattar flera datalager måste du komma åt varje datalager för att ångra ändringarna. För att förhindra att systemet förblir inkonsekvent måste du på ett tillförlitligt sätt ångra arbetet i varje datalager.
En åtgärd som implementerar eventuell konsistens lagrar inte alltid de påverkade data i en databas. I en soa-miljö (serviceorienterad arkitektur) kan en åtgärd till exempel anropa en åtgärd i en tjänst och ändra tillståndet som tjänsten har. Om du vill ångra åtgärden måste du också ångra den här tillståndsändringen, vilket kan innebära att du anropar tjänsten igen för att återställa den första åtgärdens effekter.
Lösning
Implementera en kompenserande transaktion som ångrar effekterna av slutförda steg i den ursprungliga åtgärden. Du kanske tror att du helt enkelt kan återställa systemet till dess ursprungliga tillstånd, men den här metoden kan skriva över ändringar från andra samtidiga programinstanser. I stället måste den kompenserande transaktionen på ett intelligent sätt ta hänsyn till samtidigt arbete. Den här processen är vanligtvis programspecifik och beror på den ursprungliga åtgärden.
Du kan använda ett arbetsflöde för att implementera en så småningom konsekvent åtgärd som kräver kompensation. När den ursprungliga åtgärden körs registrerar systemet information om varje steg och hur du ångrar det. Om åtgärden misslyckas spolar arbetsflödet tillbaka genom de slutförda stegen och återställer varje steg.
Varje steg är en separat åtgärd, men tillsammans utgör de en så småningom konsekvent åtgärd. Systemet måste utföra stegen och motsvarande ångra-åtgärder för varje steg. Om kunden avbryter kan dessa ångrade åtgärder köras som en kompenserande transaktion.
Ett fel i ett enda steg kräver inte alltid att du återställer hela systemet med hjälp av en kompenserande transaktion. I ett scenario med en resewebbplats bokar till exempel en kund flyg F1, F2 och F3 men kan inte boka ett rum på hotell H1. Att erbjuda kunden ett rum på ett annat hotell är att föredra framför att ställa in flygresorna. Kunden kan fortfarande välja att avbryta, vilket utlöser den kompenserande transaktionen för att ångra flygbokningarna. Kunden bör dock fatta det här beslutet, inte systemet. När beslut har stor inverkan eller är svåra att automatisera på ett tillförlitligt sätt ska du inkludera en människa i beslutsprocessen.
Tänk på följande viktiga punkter:
En kompenserande transaktion kanske inte behöver ångra processen i exakt motsatt ordning som den ursprungliga åtgärden.
Du kanske kan utföra vissa ångrade steg parallellt.
Du kan behöva tillämpa affärsspecifika regler. Om du till exempel avbryter en flygreservation kanske det inte ger kunden rätt till fullständig återbetalning.
Den här metoden liknar saga-mönstret för distribuerade transaktioner.
Kompenserande transaktioner är så småningom konsekventa åtgärder och kan misslyckas. Systemet bör registrera förloppet så att det kan återuppta den kompenserande transaktionen från felpunkten. Ett steg kan köras flera gånger när du försöker igen, så utforma varje steg som ett idempotent-kommando.
Ibland är manuella åtgärder det enda sättet att återställa från ett misslyckat steg. I dessa situationer bör systemet skapa en avisering som innehåller detaljerad information om orsaken till felet.
Problem och överväganden
Tänk på följande när du bestämmer hur du ska implementera det här mönstret:
Det är kanske inte lätt att avgöra när ett steg i en åtgärd, som implementerar eventuell konsistens, misslyckas. Ett steg kanske inte misslyckas omedelbart utan blockeras i stället. Du kan behöva implementera en timeout-mekanism.
Det är inte lätt att generalisera kompensationslogik. En kompenserande transaktion är programspecifik. Den förlitar sig på att programmet har tillräckligt med information för att ångra effekterna av varje steg i en misslyckad åtgärd.
Kompenserande transaktioner fungerar inte alltid. Definiera stegen i en kompenserande transaktion som idempotent-kommandon så att du kan upprepa dem om själva kompenserande transaktionen misslyckas.
Infrastrukturen som hanterar stegen måste uppfylla följande kriterier:
Den är motståndskraftig i både den ursprungliga operationen och den kompenserande transaktionen.
Den förlorar inte den information som krävs för att kompensera för ett felsteg.
Den övervakar på ett tillförlitligt sätt förloppet för kompensationslogik. Kompenserande transaktioner körs efter den ursprungliga transaktionens bekräftelse, och andra transaktioner kan ändra interimistiska tillstånd. Se därför till att du kan korrelera och granska både den ursprungliga åtgärden och dess ersättning från slutpunkt till slutpunkt.
En kompenserande transaktion returnerar inte nödvändigtvis systemdata till dess tillstånd i början av den ursprungliga åtgärden. I stället kompenserar transaktionen för det arbete som operationen framgångsrikt slutförde innan den misslyckades.
De kompenserande transaktionsstegen återställer inte alltid den ursprungliga åtgärden i exakt motsatt ordning. Om till exempel ett datalager är mer känsligt för inkonsekvenser än ett annat kan du ångra ändringarna i det arkivet först.
Vissa åtgärder kan hjälpa dig att förbättra framgångsgraden. Du kan placera ett kortsiktigt lås med en tidsgräns för varje resurs som krävs för att slutföra en åtgärd. Du kan hämta dessa resurser i förväg och sedan utföra arbete först när du har hämtat alla resurser. Slutför alla åtgärder innan låsen upphör att gälla.
Om du försöker använda logik som behandlar fler fel som tillfälliga kan du minimera fel som utlöser en kompenserande transaktion. När ett steg i en åtgärd som implementerar eventuell konsistens misslyckas, hantera det som ett tillfälligt undantag och försök igen med steget. Stoppa bara åtgärden och utlösa kompensationen om steget misslyckas upprepade gånger eller om du inte kan återställa den. Mer information om återförsöksstrategier finns i Tillfällig felhantering.
När du implementerar en kompenserande transaktion står du inför många utmaningar som liknar genomförandet av eventuell konsistens. Mer information finns i Minimera samordning.
Definiera tydliga punkter utan retur och oåterkalleliga steg. I komplexa arbetsflöden kan du inte på ett säkert eller meningsfullt sätt ångra vissa åtgärder, till exempel externa biverkningar eller juridiskt bindande åtgärder. Identifiera kompenserbara och oåterkalleliga steg. Utforma arbetsflödet så att oåterkalleliga steg endast inträffar när alla kritiska valideringar har slutförts.
När du ska använda det här mönstret
Använd det här mönstret i sådana här scenarier:
En affärsåtgärd omfattar flera steg, tjänster eller datalager och måste ångras om ett senare steg misslyckas. Det här scenariot inträffar ofta i långvariga arbetsflöden som följer en eventuell konsekvensmodell och inte kan förlita sig på atomiska transaktioner.
Återställning av fel kräver ofta domänspecifik logik i stället för en enkel återställning av data. Använd kompenserande åtgärder när återställning av arbetet kräver att du tillämpar affärsregler, till exempel att avbryta reservationer eller utfärda delvisa återbetalningar.
Det här mönstret kanske inte är lämpligt när:
Åtgärder kan utföras på ett säkert sätt och de flesta fel är tillfälliga. Enbart omprövningslogik räcker ofta i dessa fall, och kompenserande transaktioner ger onödig komplexitet.
Systemet kan inte tolerera tillfällig inkonsekvens, eller så kan kompensationen inte återställa ett giltigt tillstånd på ett tillförlitligt sätt. Använd starka konsekvensmekanismer eller atomiska transaktioner i alla steg i stället.
Design av arbetsbelastning
Utvärdera hur du använder kompenserande transaktioner i arbetsbelastningens design för att hantera de mål och principer som beskrivs i Azure Well-Architected Framework-pelarna. Följande tabell innehåller vägledning om hur det här mönstret stöder målen för varje pelare.
| Grundpelare | Så här stöder det här mönstret pelarmål |
|---|---|
| Tillförlitlighets designbeslut hjälper din arbetsbelastning att bli motståndskraftig mot funktionsfel och säkerställer att den återställer sig till ett fullständigt fungerande tillstånd när ett fel uppstår. | Kompensationsåtgärder åtgärdar fel i kritiska arbetsbelastningsvägar genom att använda processer som att direkt återställa dataändringar, bryta transaktionslås eller till och med köra internt systembeteende för att vända effekten. - RE:02 Kritiska flöden - RE:09 Haveriberedskap |
Om detta mönster inför kompromisser inom en pelare bör du överväga dem mot målen för de andra pelarna.
Exempel
Följande diagram visar en praktisk Azure implementering av mönstret Kompenserande transaktion. Andra implementeringar kan också fungera för dina arbetsbelastningskrav. En dirigerare som körs i Azure Container Apps samordnar varje steg i ett långvarigt arbetsflöde genom att skicka kommandon via Azure Service Bus. När varje steg framåt lyckas registrerar orkestrerare både exekveringstillstånd och motsvarande kompensationsåtgärd i databasen Azure Cosmos DB så att arbetsflödet kan återupptas, korreleras och granskas.
Den här modellen använder återförsök först för att bevara framåtförloppet. Om ett steg misslyckas tillämpar orkestratorn omprövningslogik för tillfälliga fel och försöker fortsätta den ursprungliga åtgärden. Kompensation anropas endast när framåtskridande blir omöjligt, till exempel när återförsök uttöms eller om felet klassificeras som icke-övergående.
Affärsspecifika regler kan också föredra framåtskridande framför omedelbar kompensation. Om ett steg misslyckas kan orkestreraren välja en alternativ sökväg, till exempel genom att ersätta med en motsvarande tjänst eller ett reservalternativ, i stället för att rulla tillbaka arbetsflödet. För fall med stor inverkan eller tvetydighet kan du pausa processen för mänsklig granskning innan du bestämmer om du vill fortsätta med en alternativ väg eller utlösa kompensation. Den här metoden behandlar kompensation som en sista utväg och låter domänregler driva återställningsbeslut.
I en typisk sekvens skickar orkestreraren stegmeddelanden via Service Bus (steg 1 och 2), tar emot lyckade resultat och lagrar metadata för vidarebefordran och kompensation i Azure Cosmos DB.
Du kan utlösa kompensation på två sätt:
När ett senare steg i samma arbetsbelastning misslyckas och du måste ångra tidigare lyckade steg. Den här kompensationen kan inträffa omedelbart när ett steg returnerar ett affärsfel, till exempel ett regelvalideringsfel eller när tekniska återförsök har uttömts och meddelandet flyttas till kön med obeställbara meddelanden.
När en efterföljande klient uttryckligen begär att avbryta en slutförd åtgärd.
I båda fallen läser orkestratorn de lagrade kompensationsposterna och skickar kompensationskommandon till motsvarande tjänst. Om ett kompensationssteg tillfälligt misslyckas kan Service Bus försöka igen och slutföra det utan att eskalera incidenten.
Om upprepade återförsök fortfarande misslyckas flyttar Service Bus meddelandet till en kö med obeställbara meddelanden och bevarar felinformation. Orkestratorn, eller en dedikerad dead-letter-processor, genererar en avisering och skapar strukturerad telemetri, inklusive felorsak och korrelations-ID:n, för Azure Monitor och Log Analytics, vilket kan visas i Application Insights. Den här driftvägen hjälper teamen att diagnostisera fel, fastställa behovet av manuella åtgärder och upprätthålla spårbarhet i både de ursprungliga och kompenserande flödena.
Arbetsflödet kan starta kompensation automatiskt för tydliga, lågrisktillstånd eller pausa för mänsklig granskning när situationen är tvetydig, har stor inverkan eller kräver ett manuellt beslut.
Använd hanterade identiteter och Microsoft Entra ID-baserad auktorisering mellan komponenter för att undvika delade hemligheter och framtvinga åtkomst med lägsta behörighet. När du skapar ett förenklat referensdiagram ska du behandla dessa identitets- och auktoriseringskontroller som grundläggande implementeringsproblem snarare än explicita flödessteg. Håll diagrammet fokuserat på orkestrering, återförsök, kompensation och felhantering.
Relaterade resurser
Dataöverväganden för mikrotjänster: Lär dig varför eventuell konsekvens och partiella fel är inneboende i distribuerade system. Mönstret Kompenserande transaktion ger en konkret mekanism för att hantera dessa fel när åtgärder omfattar flera tjänster.
Transactional Outbox-mönster med Azure Cosmos DB: Använd det här mönstret när kompenserande transaktioner behöver publicera händelser eller kommandon på ett tillförlitligt sätt. Det hjälper till att säkerställa att tillståndsändringar och meddelanden registreras atomiskt, vilket förhindrar meddelandeförlust.
Design för självläkning: Använd kompenserande transaktioner som en del av en självläkande strategi för dina program.
Scheduler Agent Supervisor-mönster: Använd det här mönstret för att implementera motståndskraftiga system som utför affärsåtgärder över distribuerade tjänster och resurser. Dessa system behöver ibland kompenserande transaktioner för att ångra arbetet.
Mönster för återförsök: Använd det här mönstret för att hantera tillfälliga fel och minimera behovet av kompenserande transaktioner.
Saga-mönster för distribuerade transaktioner: Använd det här mönstret för att hantera datakonsekvens mellan mikrotjänster i distribuerade transaktioner. Saga använder kompenserande transaktioner för felåterställning.
Mönster för rör och filter: Använd det här mönstret med mönstret Kompenserande transaktion som ett alternativ till distribuerade transaktioner när du delar upp komplexa uppgifter i återanvändbara steg.