sql >> Databáze >  >> NoSQL >> MongoDB

Přehled vícedokumentových ACID transakcí v MongoDB a jak je používat

Databázové systémy mají mandát zaručovat konzistenci a integritu dat, zejména pokud jde o kritická data. Tyto aspekty jsou vynucovány prostřednictvím transakcí ACID v MongoDB. ACID transakce by před provedením jakýchkoli aktualizací databáze měla splňovat určitá definovaná pravidla pro platnost dat, jinak by měla být přerušena a v databázi by se neměly provádět žádné změny. Všechny databázové transakce jsou považovány za jednu logickou operaci a během doby provádění je databáze uvedena do nekonzistentního stavu, dokud nebudou změny potvrzeny. Operace, které úspěšně mění stav databáze, se nazývají transakce zápisu, zatímco operace, které neaktualizují databázi, ale pouze načítají data, se označují jako transakce pouze pro čtení. ACID je zkratka pro atomicita, konzistence, izolace a trvanlivost.

Databáze je sdílený zdroj, ke kterému mohou přistupovat různí uživatelé v různém čase nebo ve stejnou dobu. Z tohoto důvodu může docházet k souběžným transakcím a pokud nejsou dobře spravovány, mohou mít za následek zhroucení systému, selhání hardwaru, uváznutí, pomalý výkon databáze nebo opakování provádění stejné transakce.

Co jsou pravidla ACID?

Všechny databázové systémy musí splňovat vlastnosti ACID, aby byla zaručena integrita dat.

Atomicita

Transakce je považována za jedinou jednotku operace, která může buď zcela uspět, nebo zcela selhat. Transakci nelze provést částečně. Pokud selže jakákoli podmínka konzultující transakci, celá transakce selže úplně a databáze zůstane nezměněna. Například, pokud chcete převést prostředky z účtu X na Y, zde jsou dvě transakce, první je odebrání prostředků z X a druhá je zaznamenat prostředky do Y. Pokud první transakce selže, celá transakce bude přerušena

Konzistence

Když je provedena operace, před jejím provedením je databáze v konzistentním stavu a měla by v takovém stavu zůstat po každé transakci. I když dojde k aktualizaci, transakce by měla vždy uvést databázi do platného stavu a zachovat invarianty databáze. Nemůžete například odstranit primární klíč, na který se odkazuje jako na cizí klíč v jiné kolekci. Všechna data musí splňovat definovaná omezení, aby se zabránilo poškození dat v důsledku nelegální transakce.

Izolace

Více souběžně běžících transakcí se provádí bez vzájemného ovlivnění a jejich výsledek by měl být stejný, pokud by byly prováděny postupně. Když dvě nebo více transakcí upraví stejné dokumenty v MongoDB, může dojít ke konfliktu. Databáze zjistí konflikt bezprostředně před jeho potvrzením. První operace k získání uzamčení dokumentu bude pokračovat, zatímco druhá selže a zobrazí se chybová zpráva o konfliktu.

Životnost

To nařizuje, že jakmile je transakce potvrzena, změny by měly být vždy zachovány, a to i v případě selhání systému, například kvůli výpadkům napájení nebo odpojení internetu.

Transakce MongoDB ACID

MongoDB je databáze NoSQL založená na dokumentech s flexibilním schématem. Transakce nejsou operacemi, které by se měly provádět pro každou operaci zápisu, protože mají vyšší náklady na výkon než zápis jednoho dokumentu. Díky struktuře založené na dokumentech a denormalizovanému datovému modelu bude potřeba transakcí na minimum. Vzhledem k tomu, že MongoDB umožňuje vkládání dokumentů, nemusíte nutně použít transakci ke splnění operace zápisu.

MongoDB verze 4.0 poskytuje podporu transakcí s více dokumenty pouze pro nasazení sady replik a pravděpodobně verze 4.2 rozšíří podporu pro rozštěpená nasazení (podle jejich poznámek k vydání).

Příklad transakce:

Ujistěte se, že máte nejprve nastavenou repliku. Za předpokladu, že máte databázi s názvem app a sbírku, uživatelé v prostředí Mongo Shell spouštějí následující příkazy:

$mongos a měli byste vidět něco jako uživatelské jméno:PRIMARY>

$use app

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

Musíme zahájit relaci pro naši transakci:

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

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

Pomocí této relace můžeme přidat další uživatele pomocí transakce pomocí následujících příkazů 

$session.startTransaction()

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

Zobrazí se vám WriteResult({“nInsterted“:2})

Transakce ještě nebyla potvrzena a normální $db.users.find({}) nám poskytne pouze dříve uložené uživatele. Ale pokud spustíme 

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

poslední přidaný záznam bude dostupný ve vrácených výsledcích. Pro potvrzení této transakce spustíme níže uvedený příkaz

$session.commitTransaction()

Úprava transakce je uložena v paměti, proto i po selhání budou data dostupná při obnově.

Multi-dokumentové ACID transakce v MongoDB

Toto jsou operace s více příkazy, které je třeba provádět postupně, aniž by se navzájem ovlivňovaly. Pro výše uvedený příklad můžeme vytvořit dvě transakce, jednu pro přidání uživatele a druhou pro aktualizaci uživatele s polem věku. T.j.

$session.startTransaction()

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

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

session.commit_transaction()

Transakce lze aplikovat na operace s více dokumenty obsaženými v jedné nebo více kolekcích/databázích. Jakékoli změny v důsledku transakce dokumentů neovlivní výkon pro nesouvisející pracovní zátěže nebo je nevyžadují. Dokud není transakce potvrzena, nepotvrzené zápisy nejsou replikovány do sekundárních uzlů ani nejsou čitelné mimo transakce.

Osvědčené postupy pro transakce MongoDB

Transakce s více dokumenty jsou podporovány pouze v modulu úložiště WiredTiger. Jak již bylo zmíněno, velmi málo aplikací by vyžadovalo transakce, a pokud ano, měli bychom se pokusit je zkrátit. V opačném případě pro jednu transakci ACID, pokud se pokusíte provést nadměrný počet operací, může to mít za následek vysoký tlak na mezipaměť WiredTiger. Mezipaměť je vždy diktována udržovat stav pro všechny následující zápisy od vytvoření nejstaršího snímku. To znamená, že nové zápisy se budou hromadit v mezipaměti po celou dobu trvání transakce a budou vyprázdněny pouze poté, co jsou transakce aktuálně běžící na starých snímcích potvrzeny nebo přerušeny. Pro nejlepší výkon databáze při transakci by vývojáři měli zvážit:

  1. V transakci vždy upravte malý počet dokumentů. V opačném případě budete muset transakci rozdělit na různé části a zpracovat dokumenty v různých dávkách. Najednou zpracujte maximálně 1000 dokumentů.
  2. Dočasné výjimky, jako je čekání na volbu primárních a přechodných síťových škytavek, mohou vést ke zrušení transakce. Vývojáři by měli vytvořit logiku pro opakování transakce, pokud se objeví definované chyby.
  3. Nakonfigurujte optimální trvání pro provedení transakce z výchozích 60 sekund poskytovaných MongoDB. Kromě toho použijte indexování, aby umožnilo rychlý přístup k datům v rámci transakce. Máte také možnost doladit transakci při řešení časových limitů jejím rozdělením do dávek, které umožňují její provedení v rámci časových limitů.
  4. Rozložte svou transakci na malou sadu operací tak, aby vyhovovala omezením velikosti 16 MB. V opačném případě, pokud operace spolu s popisem oplogu překročí tento limit, bude transakce přerušena.
  5. Všechna data související s entitou by měla být uložena v jediné bohaté struktuře dokumentu. Je to proto, aby se snížil počet dokumentů, které se mají ukládat do mezipaměti, když se budou měnit různá pole.

Omezení transakcí

  1. V rámci transakce nemůžete vytvořit ani zrušit kolekci.
  2. Transakce nemohou provádět zápisy do omezené kolekce
  3. Transakce se provádějí dlouho a mohou nějakým způsobem zpomalit výkon databáze.
  4. Velikost transakce je omezena na 16 MB, což vyžaduje rozdělení transakcí, které mají tendenci překračovat tuto velikost, na menší transakce.
  5. Vystavení velkého počtu dokumentů transakci může vyvinout nadměrný tlak na jádro WiredTiger, a protože se spoléhá na schopnost snapshotu, dojde k uchování velkých nevyprázdněných operací v paměti. To způsobuje určité náklady na výkon databáze.

Závěr

MongoDB verze 4.0 zavedla podporu transakcí s více dokumenty pro sady replik jako funkci zlepšení integrity a konzistence dat. Existuje však velmi málo aplikací, které by při používání MongoDB vyžadovaly transakce. Tato funkce má svá omezení, která ji činí značně nevyzrálou, pokud jde o koncept transakcí. Například transakce pro sdílený cluster nejsou podporovány a nemohou být větší než limit velikosti 16 MB. Datové modelování poskytuje lepší strukturu pro snížení počtu transakcí ve vaší databázi. Pokud neřešíte speciální případy, bude lepší se vyhnout transakcím v MongoDB.


  1. Schéma Mongoose nebylo pro model zaregistrováno

  2. Nelze spustit docker mongo image v systému Windows

  3. Problém s vracením dat načtených z dotazů DB volaných ve smyčce

  4. nastavit expiraci pro hodnoty Hashmap v Redis?