Transaktioner och låslägen i Azure Service Fabric Reliable Collections
Transaktion
En transaktion är en sekvens med åtgärder som utförs som en enda logisk arbetsenhet. Den uppvisar de gemensamma ACID-egenskaperna (atomicitet, konsekvens, isolering, hållbarhet) för databastransaktioner:
- Atomicitet: En transaktion måste vara en atomisk arbetsenhet. Med andra ord utförs antingen alla dess dataändringar eller så utförs ingen av dem.
- Konsekvens: När den är klar måste en transaktion lämna alla data i ett konsekvent tillstånd. Alla interna datastrukturer måste vara korrekta i slutet av transaktionen.
- Isolering: Ändringar som görs av samtidiga transaktioner måste isoleras från de ändringar som görs av andra samtidiga transaktioner. Isoleringsnivån som används för en åtgärd i en ITransaction bestäms av att IReliableState utför åtgärden.
- Hållbarhet: När en transaktion har slutförts är dess effekter permanent på plats i systemet. Ändringarna kvarstår även i händelse av ett systemfel.
Isoleringsnivåer
Isoleringsnivån definierar i vilken grad transaktionen måste isoleras från ändringar som gjorts av andra transaktioner. Det finns två isoleringsnivåer som stöds i Reliable Collections:
- Repeterbar läsning: Anger att instruktioner inte kan läsa data som har ändrats men ännu inte utförts av andra transaktioner och att inga andra transaktioner kan ändra data som har lästs av den aktuella transaktionen förrän den aktuella transaktionen har slutförts.
- Ögonblicksbild: Anger att data som läss av en instruktion i en transaktion är den transaktionsmässigt konsekventa versionen av de data som fanns i början av transaktionen. Transaktionen kan bara identifiera dataändringar som har genomförts före transaktionens start. Dataändringar som görs av andra transaktioner efter starten av den aktuella transaktionen är inte synliga för instruktioner som körs i den aktuella transaktionen. Effekten är som om uttrycken i en transaktion får en ögonblicksbild av de incheckade data som de fanns i början av transaktionen. Ögonblicksbilder är konsekventa mellan tillförlitliga samlingar.
Reliable Collections väljer automatiskt den isoleringsnivå som ska användas för en viss läsåtgärd beroende på åtgärden och replikens roll när transaktionen skapas. Följande är tabellen som visar standardvärden för isoleringsnivå för Reliable Dictionary- och Queue-åtgärder.
Åtgärd \ roll | Primär | Sekundära |
---|---|---|
Läsning av enskild entitet | Repeterbar läsning | Ögonblicksbild |
Uppräkning, antal | Ögonblicksbild | Ögonblicksbild |
Kommentar
Vanliga exempel för enstaka entitetsåtgärder är IReliableDictionary.TryGetValueAsync
, IReliableQueue.TryPeekAsync
.
Både Reliable Dictionary och Reliable Queue stöder Läs dina skrivningar. Med andra ord visas all skrivning i en transaktion för en följande läsning som tillhör samma transaktion.
Lås
I Reliable Collections implementerar alla transaktioner rigorös tvåfaslåsning: en transaktion släpper inte de lås som den har skaffat förrän transaktionen avslutas med antingen en avbruten eller en incheckning.
Reliable Dictionary använder låsning på radnivå för alla entitetsåtgärder.
Reliable Queue avväger samtidighet för strikt transaktionell FIFO-egenskap.
Reliable Queue använder lås på åtgärdsnivå som tillåter en transaktion med TryPeekAsync
och/eller TryDequeueAsync
och en transaktion i EnqueueAsync
taget.
Observera att för att bevara FIFO, om en TryPeekAsync
eller TryDequeueAsync
någonsin observerar att reliable queue är tom, kommer de också att låsa EnqueueAsync
.
Skrivåtgärder tar alltid exklusiva lås. För läsåtgärder beror låsning på ett par faktorer:
- Alla läsåtgärder som utförs med hjälp av ögonblicksbildisolering är låsfria.
- Alla upprepningsbara läsåtgärder tar som standard delade lås.
- För alla läsåtgärder som stöder upprepningsbar läsning kan användaren dock be om ett uppdateringslås i stället för det delade låset. Ett uppdateringslås är ett asymmetriskt lås som används för att förhindra en vanlig form av dödläge som inträffar när flera transaktioner låser resurser för potentiella uppdateringar vid ett senare tillfälle.
Kompatibilitetsmatrisen för lås finns i följande tabell:
Begäran \ Beviljad | Ingen | Delad | Uppdatera | Exklusiv |
---|---|---|---|---|
Delad | Ingen konflikt | Ingen konflikt | Konflikt | Konflikt |
Uppdatera | Ingen konflikt | Ingen konflikt | Konflikt | Konflikt |
Exklusiv | Ingen konflikt | Konflikt | Konflikt | Konflikt |
Tidsgränsargumentet i API:er för tillförlitliga samlingar används för identifiering av dödläge. Två transaktioner (T1 och T2) försöker till exempel läsa och uppdatera K1. Det är möjligt för dem att låsa sig, eftersom båda har delat lås. I det här fallet överskrider en eller båda åtgärderna tidsgränsen. I det här scenariot kan ett uppdateringslås förhindra ett sådant dödläge.