Transacties en optimistisch beheer van gelijktijdigheid

VAN TOEPASSING OP: NoSQL

Databasetransacties bieden een veilig en voorspelbaar programmeermodel voor gelijktijdige wijzigingen in de gegevens. Met traditionele relationele databases, zoals SQL Server, kunt u de bedrijfslogica schrijven met behulp van opgeslagen procedures en/of triggers en deze rechtstreeks in de database-engine naar de server verzenden voor uitvoering. Bij traditionele relationele databases moet u omgaan met twee verschillende programmeertalen, de programmeertaal (niet-transactionele) toepassingen, zoals JavaScript, Python, C#, Java, enzovoort. en de transactionele programmeertaal (zoals T-SQL) die systeemeigen wordt uitgevoerd door de database.

De database-engine in Azure Cosmos DB ondersteunt volledige ACID-compatibele transacties (Atomicity, Consistency, Isolation, Durability) met isolatie van momentopnamen. Alle databasebewerkingen binnen het bereik van de logische partitie van een container worden transactioneel uitgevoerd in de database-engine die wordt gehost door de replica van de partitie. Deze bewerkingen omvatten zowel schrijfbewerkingen (het bijwerken van een of meer items binnen de logische partitie) als leesbewerkingen. In de volgende tabel ziet u verschillende bewerkingen en transactietypen:

Bewerking Type bewerking Transactie met één of meerdere items
Invoegen (zonder een pre/post-trigger) Schrijven Transactie met één item
Invoegen (met een pre-/post-trigger) Schrijven en lezen Transactie met meerdere items
Vervangen (zonder een pre-/post-trigger) Schrijven Transactie met één item
Vervangen (door een pre-/post-trigger) Schrijven en lezen Transactie met meerdere items
Upsert (zonder een pre/post-trigger) Schrijven Transactie met één item
Upsert (met een pre-/post-trigger) Schrijven en lezen Transactie met meerdere items
Verwijderen (zonder een pre-/post-trigger) Schrijven Transactie met één item
Verwijderen (met een trigger voor/na) Schrijven en lezen Transactie met meerdere items
Opgeslagen procedure uitvoeren Schrijven en lezen Transactie met meerdere items
Door het systeem geïnitieerde uitvoering van een samenvoegingsprocedure Schrijven Transactie met meerdere items
Door het systeem geïnitieerde uitvoering van het verwijderen van items op basis van vervaldatum (TTL) van een item Schrijven Transactie met meerdere items
Lezen Lezen Transactie met één item
Feed wijzigen Lezen Transactie met meerdere items
Gepagineerd lezen Lezen Transactie met meerdere items
Gepagineerde query Lezen Transactie met meerdere items
UDF uitvoeren als onderdeel van de gepagineerde query Lezen Transactie met meerdere items

Transacties met meerdere items

Met Azure Cosmos DB kunt u opgeslagen procedures, pre/post-triggers, door de gebruiker gedefinieerde functies (UDF's) en samenvoegprocedures schrijven in JavaScript. Azure Cosmos DB biedt systeemeigen ondersteuning voor JavaScript-uitvoering binnen de database-engine. U kunt opgeslagen procedures, pre/post-triggers, door de gebruiker gedefinieerde functies (UDF's) en samenvoegprocedures in een container registreren en deze later transactioneel uitvoeren in de Azure Cosmos DB-database-engine. Het schrijven van toepassingslogica in JavaScript maakt een natuurlijke expressie mogelijk van controlestroom, variabele bereik, toewijzing en integratie van primitieven in de databasetransacties rechtstreeks in de JavaScript-taal.

De op JavaScript gebaseerde opgeslagen procedures, triggers, UDF's en samenvoegprocedures worden verpakt in een omgevings-ACID-transactie met isolatie van momentopnamen voor alle items binnen de logische partitie. Als tijdens de uitvoering van het JavaScript-programma een uitzondering wordt gegenereerd, wordt de hele transactie afgebroken en teruggedraaid. Het resulterende programmeermodel is eenvoudig maar krachtig. JavaScript-ontwikkelaars krijgen een duurzaam programmeermodel terwijl ze nog steeds hun vertrouwde taalconstructies en bibliotheekprimitief gebruiken.

De mogelijkheid om JavaScript rechtstreeks in de database-engine uit te voeren, biedt prestaties en transactionele uitvoering van databasebewerkingen voor de items van een container. Aangezien de Azure Cosmos DB-database-engine systeemeigen ondersteuning biedt voor JSON en JavaScript, komt de impedantie niet overeen tussen het type systemen van een toepassing en de database.

Optimistisch gelijktijdigheidsbeheer

Met optimistisch gelijktijdigheidsbeheer kunt u verloren updates en verwijderingen voorkomen. Gelijktijdige, conflicterende bewerkingen worden onderworpen aan de regelmatige pessimistische vergrendeling van de database-engine die wordt gehost door de logische partitie die eigenaar is van het item. Wanneer twee gelijktijdige bewerkingen proberen de nieuwste versie van een item in een logische partitie bij te werken, wint een van deze bewerkingen en mislukt de andere. Als een of twee bewerkingen om hetzelfde item gelijktijdig bij te werken eerder een oudere waarde van het item hebben gelezen, weet de database niet of de eerder gelezen waarde door een of beide conflicterende bewerkingen inderdaad de meest recente waarde van het item was. Gelukkig kan deze situatie worden gedetecteerd met het optimistische gelijktijdigheidsbeheer (OCC) voordat de twee bewerkingen de transactiegrens in de database-engine binnendringt. OCC beschermt uw gegevens tegen het per ongeluk overschrijven van wijzigingen die door anderen zijn aangebracht. Het voorkomt ook dat anderen per ongeluk uw eigen wijzigingen overschrijven.

Optimistisch gelijktijdigheidsbeheer implementeren met behulp van ETag- en HTTP-headers

Elk item dat is opgeslagen in een Azure Cosmos DB-container heeft een door het systeem gedefinieerde _etag eigenschap. De waarde van de _etag wordt automatisch gegenereerd en bijgewerkt door de server telkens wanneer het item wordt bijgewerkt. _etag kan worden gebruikt met de door de client opgegeven if-match aanvraagheader, zodat de server kan bepalen of een item voorwaardelijk kan worden bijgewerkt. De waarde van de if-match header komt overeen met de waarde van de _etag op de server. Het item wordt vervolgens bijgewerkt. Als de waarde van de if-match aanvraagheader niet meer actueel is, weigert de server de bewerking met het antwoordbericht HTTP 412-voorwaardefout. De client kan het item vervolgens opnieuw ophalen om de huidige versie van het item op de server te verkrijgen of de versie van het item op de server te overschrijven met een eigen _etag waarde voor het item. Bovendien _etag kan worden gebruikt met de if-none-match header om te bepalen of een refetch van een resource nodig is.

De waarde van het _etag item verandert telkens wanneer het item wordt bijgewerkt. Voor bewerkingen if-match voor het vervangen van items moet expliciet worden uitgedrukt als onderdeel van de aanvraagopties. Zie de voorbeeldcode in GitHub voor een voorbeeld. _etag -waarden worden impliciet gecontroleerd voor alle geschreven items die worden geraakt door de opgeslagen procedure. Als er een conflict wordt gedetecteerd, wordt met de opgeslagen procedure de transactie teruggedraaid en wordt er een uitzondering gegenereerd. Met deze methode worden alle of geen schrijfbewerkingen binnen de opgeslagen procedure atomisch toegepast. Dit is een signaal voor de toepassing om updates opnieuw toe te dienen en de oorspronkelijke clientaanvraag opnieuw uit te voeren.

Optimistisch gelijktijdigheidsbeheer en wereldwijde distributie

De gelijktijdige updates van een item worden onderworpen aan de OCC door de communicatieprotocollaag van Azure Cosmos DB. Voor Azure Cosmos DB-accounts die zijn geconfigureerd voor schrijfbewerkingen met één regio, zorgt Azure Cosmos DB ervoor dat de versie aan de clientzijde van het item dat u bijwerkt (of verwijdert) hetzelfde is als de versie van het item in de Azure Cosmos DB-container. Dit zorgt ervoor dat uw schrijfbewerkingen niet per ongeluk worden overschreven door de schrijfbewerkingen van anderen en omgekeerd. In een omgeving met meerdere gebruikers beveiligt het optimistische gelijktijdigheidsbeheer u tegen het per ongeluk verwijderen of bijwerken van een verkeerde versie van een item. Als zodanig zijn items beveiligd tegen de beruchte 'verloren update' of 'verloren verwijderen' problemen.

In een Azure Cosmos DB-account dat is geconfigureerd met schrijfbewerkingen voor meerdere regio's, kunnen gegevens onafhankelijk worden doorgevoerd in secundaire regio's als _etag deze overeenkomen met die van de gegevens in de lokale regio. Zodra nieuwe gegevens lokaal zijn doorgevoerd in een secundaire regio, worden deze samengevoegd in de hub of primaire regio. Als het conflictoplossingsbeleid de nieuwe gegevens samenvoegt in de hubregio, worden deze gegevens vervolgens globaal gerepliceerd met de nieuwe _etag. Als het conflictoplossingsbeleid de nieuwe gegevens weigert, wordt de secundaire regio teruggedraaid naar de oorspronkelijke gegevens en _etag.

Volgende stappen

Meer informatie over databasetransacties en optimistisch gelijktijdigheidsbeheer vindt u in de volgende artikelen: