Delen via


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. Met traditionele relationele databases moet u omgaan met twee verschillende programmeertalen, de programmeertaal (niet-transactionele) toepassing, 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-transacties (Atomiciteit, Consistentie, Isolatie, Duurzaamheid) die compatibel zijn met momentopname-isolatie. Alle databasebewerkingen binnen het bereik van de logische partitie van een container worden transactioneel uitgevoerd binnen de database-engine die wordt gehost door de replica van de partitie. Deze bewerkingen omvatten zowel schrijven (een of meer items binnen de logische partitie bijwerken) als leesbewerkingen. De volgende tabel illustreert verschillende bewerkingen en transactietypen:

Bewerking Type bewerking Transactie met één of meerdere items
Invoegen (zonder een voorafgaande/post-trigger) Schrijven Transactie met één item
Invoegen (met een voorafgaande/post-trigger) Schrijven en lezen Transactie met meerdere items
Vervangen (zonder een voorafgaande/post-trigger) Schrijven Transactie met één item
Vervangen (door een pre/post-trigger) Schrijven en lezen Transactie met meerdere items
Upsert (zonder een voorafgaande/post-trigger) Schrijven Transactie met één item
Upsert (met een pre/post-trigger) Schrijven en lezen Transactie met meerdere items
Verwijderen (zonder een voorafgaande/post-trigger) Schrijven Transactie met één item
Verwijderen (met een voorafgaande/post-trigger) 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 samenvoegprocedure 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 Read Transactie met meerdere items
Gepagineerd lezen Read Transactie met meerdere items
Gepagineerde query Read Transactie met meerdere items
UDF uitvoeren als onderdeel van de gepagineerde query Read Transactie met meerdere items

Transacties met meerdere items

Met Azure Cosmos DB kunt u opgeslagen procedures schrijven , pre/post-triggers, door de gebruiker gedefinieerde functies (UDF's) en samenvoegprocedures in JavaScript. Azure Cosmos DB biedt systeemeigen ondersteuning voor JavaScript-uitvoering in de database-engine. U kunt opgeslagen procedures, pre/post-triggers, door de gebruiker gedefinieerde functies (UDF's) en samenvoegprocedures registreren voor een container en deze later transactioneel uitvoeren in de Azure Cosmos DB-database-engine. Het schrijven van toepassingslogica in JavaScript maakt natuurlijke expressie mogelijk van controlestroom, variabele bereik, toewijzing en integratie van primitieven voor het verwerken van uitzonderingen binnen 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 op basis van de items van een container. Aangezien azure Cosmos DB-database-engine systeemeigen ondersteuning biedt voor JSON en JavaScript, komt de impedantie bovendien 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 reguliere 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 echter een of twee bewerkingen die tegelijkertijd hetzelfde item probeerde bij te werken, eerder een oudere waarde van het item hadden gelezen, weet de database niet of de eerder gelezen waarde door een van beide 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 binnen de database-engine kunnen invoeren. OCC beveiligt uw gegevens tegen het per ongeluk overschrijven van wijzigingen die door anderen zijn aangebracht. Het voorkomt ook dat anderen uw eigen wijzigingen per ongeluk 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 het _etag item wordt automatisch gegenereerd en bijgewerkt door de server telkens wanneer het item wordt bijgewerkt. _etag kan worden gebruikt met de door de client geleverde 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 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 overschrijven met een eigen _etag waarde voor het item. Daarnaast _etag kunt u met de if-none-match header gebruiken om te bepalen of een verw-verbinding van een resource nodig is.

De waarde van _etag het item verandert telkens wanneer het item wordt bijgewerkt. Voor vervangingsitembewerkingen if-match moet u expliciet worden uitgedrukt als onderdeel van de aanvraagopties. Zie de voorbeeldcode in GitHub voor een voorbeeld. _etag waarden worden impliciet gecontroleerd op alle geschreven items die worden aangeraakt door de opgeslagen procedure. Als er een conflict wordt gedetecteerd, wordt de transactie teruggedraaid door de opgeslagen procedure 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 wijzen 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 in éé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 worden beschermd tegen overschrijven per ongeluk door de schrijfbewerkingen van anderen en vice versa. In een omgeving met meerdere gebruikers beschermt het optimistische gelijktijdigheidsbeheer u tegen het per ongeluk verwijderen of bijwerken van een verkeerde versie van een item. Als zodanig worden items beschermd tegen de beruchte problemen met 'verloren update' of 'verloren verwijdering'.

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 overeenkomt 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 wereldwijd 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: