sql >> Databasteknik >  >> NoSQL >> MongoDB

En översikt över ACID-transaktioner med flera dokument i MongoDB och hur man använder dem

Databassystem har mandat att garantera datakonsistens och integritet, särskilt när kritisk data är inblandad. Dessa aspekter upprätthålls genom ACID-transaktioner i MongoDB. En ACID-transaktion bör uppfylla vissa definierade regler för datavaliditet innan du gör några uppdateringar av databasen, annars bör den avbrytas och inga ändringar ska göras i databasen. Alla databastransaktioner betraktas som en enda logisk operation och under exekveringstiden försätts databasen i ett inkonsekvent tillstånd tills ändringarna har genomförts. Operationer som framgångsrikt ändrar databasens tillstånd kallas skrivtransaktioner medan de som inte uppdaterar databasen utan bara hämtar data kallas skrivskyddade transaktioner. ACID är en akronym för Atomicity, Consistency, Isolation och Durability.

En databas är en delad resurs som kan nås av olika användare vid olika eller samtidigt. Av denna anledning kan samtidiga transaktioner inträffa och om de inte hanteras väl kan de resultera i systemkraschar, maskinvarufel, dödläge, långsam databasprestanda eller upprepning i utförandet av samma transaktion.

Vad är ACID-regler?

Alla databassystem måste uppfylla ACID-egenskaperna för att garantera dataintegritet.

Atomicitet

En transaktion betraktas som en enda operationsenhet som antingen kan lyckas helt eller misslyckas helt. En transaktion kan inte utföras delvis. Om något villkor som konsulterar en transaktion misslyckas, kommer hela transaktionen att misslyckas helt och databasen förblir oförändrad. Till exempel, om du vill överföra pengar från konto X till Y, finns det två transaktioner, den första är att ta bort pengar från X och den andra är att registrera pengarna i Y. Om den första transaktionen misslyckas, hela transaktionen kommer att avbrytas

Konsistens

När en operation utfärdas, före exekvering, är databasen i ett konsekvent tillstånd och det bör förbli så efter varje transaktion. Även om det finns en uppdatering, bör transaktionen alltid föra databasen till ett giltigt tillstånd och bibehålla databasens invarianter. Du kan till exempel inte ta bort en primärnyckel som har refererats till som en främmande nyckel i en annan samling. All data måste uppfylla de definierade begränsningarna för att förhindra datakorruption från en olaglig transaktion.

Isolering

Flera transaktioner som körs samtidigt exekveras utan att påverka varandra och deras resultat bör vara detsamma om de skulle köras sekventiellt. När två eller flera transaktioner ändrar samma dokument i MongoDB kan det uppstå en konflikt. Databasen kommer att upptäcka en konflikt omedelbart innan den begås. Den första operationen för att få ett lås på dokumentet kommer att fortsätta medan den andra kommer att misslyckas och ett konfliktfelmeddelande kommer att visas.

Hållbarhet

Detta dikterar att, när transaktionen väl har genomförts, bör ändringarna upprätthållas hela tiden även vid en händelse av ett systemfel, till exempel på grund av strömavbrott eller internetavbrott.

MongoDB ACID-transaktioner

MongoDB är en dokumentbaserad NoSQL-databas med ett flexibelt schema. Transaktioner är inte operationer som bör utföras för varje skrivoperation eftersom de medför en högre prestandakostnad över en enda dokumentskrivning. Med en dokumentbaserad struktur och denormaliserad datamodell kommer det att finnas ett minimerat behov av transaktioner. Eftersom MongoDB tillåter inbäddning av dokument behöver du inte nödvändigtvis använda en transaktion för att möta en skrivoperation.

MongoDB version 4.0 tillhandahåller transaktionsstöd för flera dokument endast för implementeringar av replikuppsättningar och förmodligen kommer version 4.2 att utöka stödet för fragmenterade distributioner (enligt deras releasenotes).

Exempel på en transaktion:

Se till att du har en replikuppsättning på plats först. Förutsatt att du har en databas som heter app och en samling användare i Mongo Shell kör följande kommandon:

$mongos och du borde se något som användarnamn:PRIMARY>

$use app

$db.users.insert([{_id:1, name: ‘Brian’}, {_id:2, name: ‘Sheila’}, {_id:3, name: ‘James’}])

Vi måste starta en session för vår transaktion:

$db.getMongo().startSession() and you should see something like 

session { "id" : UUID("dcfa8de5-627d-3b1c-a890-63c9a355520c") }

Med den här sessionen kan vi lägga till fler användare med en transaktion med följande kommandon 

$session.startTransaction()

session.getDatabase(‘app’).users.insert({_id:4, name:  ‘Hitler’})

Du kommer att presenteras med WriteResult({“nInsterted”:2})

Transaktionen har ännu inte genomförts och den normala $db.users.find({}) ger oss endast tidigare sparade användare. Men om vi kör 

$session.getDatabase(“app”).users.find()

den senast tillagda posten kommer att vara tillgänglig i de returnerade resultaten. För att utföra denna transaktion kör vi kommandot nedan

$session.commitTransaction()

Transaktionsändringen lagras i minnet och det är därför även efter misslyckande data kommer att vara tillgängliga vid återställning.

ACID-transaktioner med flera dokument i MongoDB

Detta är operationer med flera påståenden som måste utföras sekventiellt utan att påverka varandra. För exemplet ovan kan vi skapa två transaktioner, en för att lägga till en användare och en annan för att uppdatera en användare med ett åldersfält. Dvs

$session.startTransaction()

   db.users.insert({_id:6, name “Ibrahim”})

   db.users.updateOne({_id:3 , {$set:{age:50}}})

session.commit_transaction()

Transaktioner kan tillämpas på operationer mot flera dokument som finns i en eller flera samlingar/databaser. Eventuella ändringar på grund av dokumenttransaktioner påverkar inte prestanda för arbetsbelastningar som inte är relaterade eller kräver dem inte. Tills transaktionen har genomförts, replikeras varken obekräftade skrivningar till de sekundära noderna eller är läsbara utanför transaktionerna.

Bästa metoder för MongoDB-transaktioner

Transaktioner med flera dokument stöds endast i WiredTiger-lagringsmotorn. Som nämnts tidigare skulle väldigt få applikationer kräva transaktioner och i så fall bör vi försöka göra dem korta. Annars, för en enskild ACID-transaktion, om du försöker utföra ett för stort antal operationer, kan det resultera i högt tryck på WiredTiger-cachen. Cachen är alltid dikterad att bibehålla tillståndet för alla efterföljande skrivningar sedan den äldsta ögonblicksbilden skapades. Detta innebär att nya skrivningar kommer att ackumuleras i cachen under hela transaktionens varaktighet och kommer att tömmas först efter att transaktioner som för närvarande körs på gamla ögonblicksbilder har begåtts eller avbrutits. För bästa databasprestanda för transaktionen bör utvecklare överväga:

  1. Ändra alltid ett litet antal dokument i en transaktion. Annars måste du dela upp transaktionen i olika delar och bearbeta dokumenten i olika omgångar. Behandla som mest 1000 dokument åt gången.
  2. Tillfälliga undantag som att vänta på att välja primära och övergående nätverkshickor kan resultera i abort av transaktionen. Utvecklare bör skapa en logik för att försöka genomföra transaktionen igen om de definierade felen presenteras.
  3. Konfigurera optimal varaktighet för utförandet av transaktionen från standard 60 sekunder från MongoDB. Använd dessutom indexering så att det kan tillåta snabb dataåtkomst inom transaktionen. Du har också flexibiliteten att finjustera transaktionen när det gäller att åtgärda timeouts genom att dela upp den i batcher som tillåter dess exekvering inom tidsgränserna.
  4. Dekomponera din transaktion i en liten uppsättning operationer så att den passar storleksbegränsningarna på 16 MB. Annars, om operationen tillsammans med oplogbeskrivningen överskrider denna gräns, kommer transaktionen att avbrytas.
  5. All data som rör en enhet bör lagras i en enda, rik dokumentstruktur. Detta för att minska antalet dokument som ska cachelagras när olika fält ska ändras.

Begränsningar för transaktioner

  1. Du kan inte skapa eller släppa en samling i en transaktion.
  2. Transaktioner kan inte göra skrivningar till en begränsad samling
  3. Transaktioner tar mycket tid att utföra och på något sätt kan de bromsa databasens prestanda.
  4. Transaktionsstorleken är begränsad till 16 MB, vilket kräver att man delar upp alla som tenderar att överskrida denna storlek i mindre transaktioner.
  5. Att utsätta ett stort antal dokument för en transaktion kan utöva överdrivet tryck på WiredTiger-motorn och eftersom den förlitar sig på ögonblicksbildskapaciteten kommer det att finnas kvar stora opererade operationer i minnet. Detta ger en viss prestandakostnad på databasen.

Slutsats

MongoDB version 4.0 introducerade transaktionsstöd för flera dokument för replikuppsättningar som en funktion för att förbättra dataintegriteten och konsistensen. Det finns dock väldigt få applikationer som skulle kräva transaktioner när du använder MongoDB. Det finns begränsningar mot denna funktion som gör den betydligt lite omogen när det gäller transaktionskonceptet. Till exempel stöds inte transaktioner för ett fragmenterat kluster och de kan inte vara större än en storleksgräns på 16 MB. Datamodellering ger en bättre struktur för att minska transaktioner i din databas. Såvida du inte har att göra med speciella fall är det bättre att undvika transaktioner i MongoDB.


  1. Hur får man storleken på ett enda dokument i Mongodb?

  2. I NodeJS, hur matar man ut resultat från mongodb med olika fältnamn?

  3. MongoDB frågar prestanda för över 5 miljoner poster

  4. Filtrera array med $in-operatorn i $projektstadiet