Delen via


Transacties en optimistische gelijktijdigheidscontrole

VAN TOEPASSING OP: NoSQL

Databasetransacties bieden een veilig en voorspelbaar programmeermodel voor gelijktijdige wijzigingen in de gegevens. Traditionele relationele databases, zoals SQL Server, bieden u de mogelijkheid om de bedrijfslogica te schrijven met behulp van opgeslagen procedures en triggers, en deze vervolgens rechtstreeks in de database-engine naar de server te verzenden voor uitvoering.

Met traditionele relationele databases moet u omgaan met twee verschillende programmeertalen: een programmeertaal voor niet-transactionele toepassingen, zoals JavaScript, Python, C# of Java; en een 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 in 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 bevat verschillende bewerkingen en transactietypen:

Operatie Bewerkingstype Transactie met één of meerdere items
Invoegen (zonder een voorafgaande/post-trigger) Schrijven Transactie met één item
Invoegen (met een vooraf- of natrigger) Schrijven en lezen Transactie met meerdere items
Vervangen (zonder voorafgaande of daaropvolgende 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 pre- en 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 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, triggers en door de gebruiker gedefinieerde functies schrijven en procedures samenvoegen 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 het JavaScript-programma tijdens de uitvoering een uitzondering genereert, 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 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 (OCC) 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 conflicterende bewerkingen inderdaad de meest recente waarde van het item was.

Gelukkig kan deze situatie worden gedetecteerd met de OCC voordat de twee bewerkingen de transactiegrens binnen de database-engine kunnen invoeren. De 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. Als de waarde van de if-match header overeenkomt met de waarde van de _etag server, wordt het item 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 zijn eigen _etag waarde voor het item. Daarnaast kan _etag met de if-none-match header worden gebruikt om te bepalen of een verversing van een resource nodig is.

De waarde van _etag het item verandert telkens wanneer het item wordt bijgewerkt. Voor bewerkingen voor het vervangen van items moet if-match expliciet worden aangegeven als onderdeel van de verzoekopties. Zie de voorbeeldcode in GitHub voor een voorbeeld. De _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 door de opgeslagen procedure 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 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 het per ongeluk overschrijven door de bewerkingen van anderen, en vice versa. In een omgeving met meerdere gebruikers beveiligt het optimistische gelijktijdigheidsbeheer u tegen het per ongeluk verwijderen of bijwerken van de 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 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: