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: