Kontroll över transaktioner och optimistisk samtidighet
GÄLLER FÖR: NoSQL
Databastransaktioner ger en säker och förutsägbar programmeringsmodell för att hantera samtidiga ändringar av data. Med traditionella relationsdatabaser, till exempel SQL Server, kan du skriva affärslogik med lagrade procedurer och/eller utlösare, skicka den till servern för körning direkt i databasmotorn. Med traditionella relationsdatabaser måste du hantera två olika programmeringsspråk (icke-transaktionella) programprogram, till exempel JavaScript, Python, C#, Java osv. och det transaktionella programmeringsspråket (till exempel T-SQL) som körs internt av databasen.
Databasmotorn i Azure Cosmos DB stöder fullständiga ACID-kompatibla transaktioner (atomicitet, konsekvens, isolering, hållbarhet) med ögonblicksbildisolering. Alla databasåtgärder inom omfånget för en container logiska partition körs transaktionsmässigt i databasmotorn som hanteras av repliken av partitionen. Dessa åtgärder omfattar både skrivning (uppdatering av ett eller flera objekt i den logiska partitionen) och läsåtgärder. I följande tabell visas olika åtgärder och transaktionstyper:
Åtgärd | Åtgärdstyp | Transaktion med en eller flera objekt |
---|---|---|
Infoga (utan en pre/post-utlösare) | Skriva | Transaktion med enstaka objekt |
Infoga (med en pre/post-utlösare) | Skriva och läsa | Transaktion med flera objekt |
Ersätt (utan en pre/post-utlösare) | Skriva | Transaktion med enstaka objekt |
Ersätt (med en pre/post-utlösare) | Skriva och läsa | Transaktion med flera objekt |
Upsert (utan en pre/post-utlösare) | Skriva | Transaktion med enstaka objekt |
Upsert (med en pre/post-utlösare) | Skriva och läsa | Transaktion med flera objekt |
Ta bort (utan en pre/post-utlösare) | Skriva | Transaktion med enstaka objekt |
Ta bort (med en pre/post-utlösare) | Skriva och läsa | Transaktion med flera objekt |
Utför lagrad procedur | Skriva och läsa | Transaktion med flera objekt |
Systeminitierad körning av en sammanslagningsprocedur | Skriva | Transaktion med flera objekt |
Systeminitierad körning av borttagning av objekt baserat på förfallodatum (TTL) för ett objekt | Skriva | Transaktion med flera objekt |
Lästa | Läsa | Transaktion med ett objekt |
Ändringsflöde | Lästa | Transaktion med flera objekt |
Sidnumrerad läsning | Lästa | Transaktion med flera objekt |
Sidnumrerad fråga | Lästa | Transaktion med flera objekt |
Kör UDF som en del av den sidnumrerade frågan | Lästa | Transaktion med flera objekt |
Transaktioner med flera objekt
Med Azure Cosmos DB kan du skriva lagrade procedurer, pre/post-utlösare, användardefinierade funktioner (UDF:er) och sammanslagningsprocedurer i JavaScript. Azure Cosmos DB har inbyggt stöd för JavaScript-körning i databasmotorn. Du kan registrera lagrade procedurer, pre/post-utlösare, användardefinierade funktioner (UDF:er) och sammanslagningsprocedurer på en container och senare köra dem transaktionsmässigt i Azure Cosmos DB-databasmotorn. Genom att skriva programlogik i JavaScript kan du använda naturligt uttryck för kontrollflöde, variabelomfång, tilldelning och integrering av undantagshantering av primitiver i databastransaktionerna direkt på JavaScript-språket.
JavaScript-baserade lagrade procedurer, utlösare, UDF:er och sammanslagningsprocedurer omsluts i en omgivande ACID-transaktion med ögonblicksbildisolering över alla objekt i den logiska partitionen. Om JavaScript-programmet genererar ett undantag under körningen avbryts och återställs hela transaktionen. Den resulterande programmeringsmodellen är enkel men ändå kraftfull. JavaScript-utvecklare får en hållbar programmeringsmodell samtidigt som de använder sina välbekanta språkkonstruktioner och bibliotekspri primitiver.
Möjligheten att köra JavaScript direkt i databasmotorn ger prestanda och transaktionell körning av databasåtgärder mot objekten i en container. Eftersom Azure Cosmos DB-databasmotorn har inbyggt stöd för JSON och JavaScript finns det dessutom inget matchningsfel mellan typsystemen för ett program och databasen.
Optimistisk samtidighetskontroll
Optimistisk samtidighetskontroll gör att du kan förhindra förlorade uppdateringar och borttagningar. Samtidiga, motstridiga åtgärder utsätts för regelbunden pessimistisk låsning av databasmotorn som hanteras av den logiska partition som äger objektet. När två samtidiga åtgärder försöker uppdatera den senaste versionen av ett objekt i en logisk partition vinner den ena och den andra misslyckas. Men om en eller två åtgärder som försöker uppdatera samma objekt tidigare hade läst ett äldre värde för objektet, vet databasen inte om det tidigare läsvärdet av någon av eller båda de motstridiga åtgärderna verkligen var det senaste värdet för objektet. Som tur är kan den här situationen identifieras med optimistisk samtidighetskontroll (OCC) innan de två åtgärderna får komma in i transaktionsgränsen i databasmotorn. OCC skyddar dina data från att oavsiktligt skriva över ändringar som har gjorts av andra. Det förhindrar också att andra oavsiktligt skriver över dina egna ändringar.
Implementera optimistisk samtidighetskontroll med hjälp av ETag- och HTTP-huvuden
Varje objekt som lagras i en Azure Cosmos DB-container har en systemdefinierad _etag
egenskap. Värdet för _etag
genereras och uppdateras automatiskt av servern varje gång objektet uppdateras. _etag
kan användas med den angivna begäranderubriken if-match
för klienten så att servern kan avgöra om ett objekt kan uppdateras villkorligt. Värdet för if-match
rubriken matchar värdet _etag
för på servern, objektet uppdateras sedan. Om värdet för if-match
begärandehuvudet inte längre är aktuellt avvisar servern åtgärden med svarsmeddelandet "HTTP 412-förhandsvillkorsfel". Klienten kan sedan hämta objektet igen för att hämta den aktuella versionen av objektet på servern eller åsidosätta versionen av objektet på servern med sitt eget _etag
värde för objektet. Dessutom _etag
kan användas med if-none-match
huvudet för att avgöra om en referens av en resurs behövs.
Objektets _etag
värde ändras varje gång objektet uppdateras. För ersätt objektåtgärder if-match
måste uttryckligen uttryckas som en del av alternativen för begäran. Ett exempel finns i exempelkoden i GitHub. _etag
värden kontrolleras implicit för alla skrivna objekt som berörs av den lagrade proceduren. Om någon konflikt identifieras återställer den lagrade proceduren transaktionen och utlöser ett undantag. Med den här metoden tillämpas antingen alla eller inga skrivningar i den lagrade proceduren atomiskt. Detta är en signal till programmet att tillämpa uppdateringarna på nytt och försöka utföra den ursprungliga klientbegäran igen.
Optimistisk samtidighetskontroll och global distribution
Samtidiga uppdateringar av ett objekt utsätts för OCC av Azure Cosmos DB:s kommunikationsprotokollskikt. För Azure Cosmos DB-konton som konfigurerats för skrivningar i en region ser Azure Cosmos DB till att klientsidans version av objektet som du uppdaterar (eller tar bort) är densamma som versionen av objektet i Azure Cosmos DB-containern. Detta säkerställer att dina skrivningar skyddas från att skrivas över av misstag av andras skrivningar och vice versa. I en miljö med flera användare skyddar den optimistiska samtidighetskontrollen dig från att oavsiktligt ta bort eller uppdatera fel version av ett objekt. Därför skyddas objekt mot de ökända problemen "förlorad uppdatering" eller "förlorad borttagning".
I ett Azure Cosmos DB-konto som konfigurerats med skrivningar i flera regioner kan data checkas in oberoende av varandra i sekundära regioner om _etag
de matchar data i den lokala regionen. När nya data har bekräftats lokalt i en sekundär region sammanfogas de sedan i hubben eller den primära regionen. Om konfliktlösningsprincipen sammanfogar de nya data i hubbregionen replikeras dessa data globalt med den nya _etag
. Om konfliktlösningsprincipen avvisar nya data återställs den sekundära regionen till de ursprungliga data och _etag
.
Nästa steg
Läs mer om databastransaktioner och optimistisk samtidighetskontroll i följande artiklar: