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: