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 dataändringar. Med traditionella relationsdatabaser, till exempel SQL Server, kan du skriva affärslogik med hjälp av lagrade procedurer och/eller utlösare, och skicka den till servern för körning direkt i databasmotorn. Med traditionella relationsdatabaser måste du hantera två olika programmeringsspråk som programmeringsspråket (icke-transaktionell) som JavaScript, Python, C#, Java osv. och det transaktionsbaserade programmeringsspråket (till exempel T-SQL) som körs internt av databasen.

Databasmotorn i Azure Cosmos DB stöder fullständiga ACID-kompatibla transaktioner (Atomicity, Consistency, Isolation, Durability) med ögonblicksbildisolering. Alla databasåtgärder inom omfånget för en containers logiska partition körs transaktionsmässigt i databasmotorn som hanteras av partitionens replik. Dessa åtgärder omfattar både skrivning (uppdatering av ett eller flera objekt i den logiska partitionen) och läsåtgärder. Följande tabell illustrerar 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 ett 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 ett 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 ett 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 ett objekt
Ta bort (med en pre/post-utlösare) Skriva och läsa Transaktion med flera objekt
Köra 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äsa Läsa Transaktion med ett objekt
Ändringsflöde Läsa Transaktion med flera objekt
Sidnumrerad läsning Läsa Transaktion med flera objekt
Sidnumrerad fråga Läsa Transaktion med flera objekt
Köra UDF som en del av den sidnumrerade frågan Läsa 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 hela transaktionen och återställs. Den resulterande programmeringsmodellen är enkel men kraftfull. JavaScript-utvecklare får en hållbar programmeringsmodell samtidigt som de använder sina välbekanta språkkonstruktioner och biblioteksprimitiver.

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 kan 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 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 klientens angivna if-match begärandehuvud 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 Villkorsfel". Klienten kan sedan hämta objektet igen för att hämta den aktuella versionen av objektet på servern eller åsidosätta objektversionen på servern med ett 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 att ersätta objektåtgärder if-match måste uttryckligen uttryckas som en del av begärandealternativen. 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 en 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 igen 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 enda region ser Azure Cosmos DB till att klientversionen av objektet som du uppdaterar (eller tar bort) är samma 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 med "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 checkas in lokalt i en sekundär region slås de samman i hubben eller den primära regionen. Om konfliktlösningsprincipen sammanfogar nya data till hubbregionen replikeras dessa data globalt med den nya _etag. Om konfliktlösningsprincipen avvisar nya data återställs den sekundära regionen till ursprungliga data och _etag.

Nästa steg

Läs mer om databastransaktioner och optimistisk samtidighetskontroll i följande artiklar: