MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Преглед на многодокументните ACID транзакции в MongoDB и как да ги използвате

Системите за бази данни имат мандат да гарантират последователност и цялост на данните, особено когато са включени критични данни. Тези аспекти се прилагат чрез ACID транзакции в MongoDB. Транзакцията ACID трябва да отговаря на някои определени правила за валидност на данните, преди да направи каквито и да било актуализации на базата данни, в противен случай тя трябва да бъде прекратена и няма да се правят промени в базата данни. Всички транзакции на база данни се считат за единична логическа операция и по време на изпълнението базата данни се поставя в непоследователно състояние, докато промените не бъдат приети. Операциите, които успешно променят състоянието на базата данни, се наричат ​​транзакции за запис, докато тези, които не актуализират базата данни, а само извличат данни, се наричат ​​транзакции само за четене. ACID е акроним за атомност, консистенция, изолация и издръжливост.

База данни е споделен ресурс, който може да бъде достъпен от различни потребители по различно или по едно и също време. Поради тази причина може да се случат едновременни транзакции и ако не се управляват добре, те могат да доведат до системни сривове, хардуерен отказ, блокиране, бавна производителност на базата данни или повторение при изпълнението на същата транзакция.

Какви са правилата за ACID?

Всички системи за бази данни трябва да отговарят на свойствата на ACID, за да се гарантира целостта на данните.

Атомарност

Транзакцията се счита за отделна единица операция, която може или да успее напълно, или да се провали напълно. Транзакцията не може да бъде изпълнена частично. Ако някое условие, консултиращо транзакция, се провали, цялата транзакция ще се провали напълно и базата данни ще остане непроменена. Например, ако искате да прехвърлите средства от сметка X към Y, тук има две транзакции, първата е да премахнете средства от X, а втората е да запишете средствата в Y. Ако първата транзакция се провали, цялата транзакцията ще бъде прекратена

Последователност

Когато е издадена операция, преди изпълнение, базата данни е в последователно състояние и трябва да остане такова след всяка транзакция. Дори ако има актуализация, транзакцията винаги трябва да доведе базата данни до валидно състояние, като поддържа инвариантите на базата данни. Например, не можете да изтриете първичен ключ, който е посочен като външен ключ в друга колекция. Всички данни трябва да отговарят на дефинираните ограничения, за да се предотврати повреда на данните от незаконна транзакция.

Изолация

Множество транзакции, изпълнявани едновременно, се изпълняват, без да се влияят една на друга и резултатът им трябва да е един и същ, ако трябва да се изпълняват последователно. Когато две или повече транзакции променят едни и същи документи в MongoDB, може да има конфликт. Базата данни ще открие конфликт непосредствено преди да бъде ангажиран. Първата операция за придобиване на заключване на документа ще продължи, докато другата ще се провали и ще се покаже съобщение за конфликтна грешка.

Издръжливост

Това диктува, че след като транзакцията е ангажирана, промените трябва да се поддържат по всяко време, дори в случай на системна повреда, например поради прекъсване на захранването или прекъсване на връзката с интернет.

Транзакции на MongoDB ACID

MongoDB е базирана на документи  NoSQL база данни с гъвкава схема. Транзакциите не са операции, които трябва да се изпълняват за всяка операция на запис, тъй като те водят до по-високи разходи за производителност в сравнение с едно записване на един документ. С документно базирана структура и денормализиран модел на данни ще има минимизирана нужда от транзакции. Тъй като MongoDB позволява вграждане на документи, не е задължително да използвате транзакция, за да изпълните операция за запис.

MongoDB версия 4.0 осигурява поддръжка на транзакции с множество документи само за внедряване на набор от реплики и вероятно версията 4.2 ще разшири поддръжката за разчленени внедрявания (съгласно техните бележки по версията).

Пример за транзакция:

Първо се уверете, че имате настроена реплика. Ако приемем, че имате база данни, наречена app и колекция потребители в Mongo Shell, изпълнете следните команди:

$mongos и трябва да видите нещо като потребителско име:PRIMARY>

$use app

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

Трябва да започнем сесия за нашата транзакция:

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

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

С помощта на тази сесия можем да добавим още потребители чрез транзакция със следните команди 

$session.startTransaction()

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

Ще ви бъде представен WriteResult({“nInsterted”:2})

Транзакцията все още не е ангажирана и нормалният $db.users.find({}) ще ни даде само предварително запазените потребители. Но ако стартираме 

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

последният добавен запис ще бъде наличен в върнатите резултати. За да извършим тази транзакция, изпълняваме командата по-долу

$session.commitTransaction()

Промяната на транзакцията се съхранява в паметта, поради което дори и след неуспех данните ще бъдат налични при възстановяване.

Многодокументни ACID транзакции в MongoDB

Това са операции с множество оператори, които трябва да се изпълняват последователно, без да се засягат една друга. За извадката по-горе можем да създадем две транзакции, една за добавяне на потребител и друга за актуализиране на потребител с поле за възраст. т.е.

$session.startTransaction()

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

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

session.commit_transaction()

Транзакциите могат да се прилагат към операции срещу множество документи, съдържащи се в една или много колекция/база данни. Всички промени, дължащи се на транзакция с документи, не оказват влияние върху производителността за натоварвания, които не са свързани или не ги изискват. Докато транзакцията не бъде ангажирана, необвързаните записи нито се репликират на вторичните възли, нито са четими извън транзакциите.

Най-добри практики за транзакции на MongoDB

Транзакциите с множество документи се поддържат само в механизма за съхранение на WiredTiger. Както споменахме по-горе, много малко приложения биха изисквали транзакции и ако е така, трябва да се опитаме да ги направим кратки. В противен случай, за една транзакция ACID, ако се опитате да извършите прекомерен брой операции, това може да доведе до висок натиск върху кеша на WiredTiger. Кешът винаги е продиктуван да поддържа състояние за всички следващи записи след създаването на най-старата моментна снимка. Това означава, че новите записи ще се натрупват в кеша през цялото времетраене на транзакцията и ще бъдат изтрити само след като транзакциите, които в момента се изпълняват върху стари моментни снимки, бъдат извършени или прекратени. За най-добра производителност на базата данни за транзакцията, разработчиците трябва да имат предвид:

  1. Винаги променяйте малък брой документи в транзакция. В противен случай ще трябва да разделите транзакцията на различни части и да обработите документите в различни партиди. Обработвайте най-много 1000 документа наведнъж.
  2. Временни изключения, като например изчакване на избор на първична и преходна мрежа, могат да доведат до прекъсване на транзакцията. Разработчиците трябва да установят логика за повторен опит за транзакция, ако бъдат представени дефинираните грешки.
  3. Конфигурирайте оптимална продължителност за изпълнение на транзакцията от 60 секунди по подразбиране, предоставени от MongoDB. Освен това използвайте индексиране, за да може да позволи бърз достъп до данни в рамките на транзакцията. Освен това имате гъвкавостта да прецизирате транзакцията при адресиране на изчакване, като я разделите на партиди, които позволяват изпълнението й в рамките на сроковете.
  4. Разложете транзакцията си на малък набор от операции, така че да отговаря на ограниченията за размер от 16 МБ. В противен случай, ако операцията заедно с описанието на oplog надвиши това ограничение, транзакцията ще бъде прекратена.
  5. Всички данни, свързани с даден обект, трябва да се съхраняват в една богата структура на документа. Това е с цел намаляване на броя на документите, които трябва да се кешират, когато различните полета ще се променят.

Ограничения на транзакциите

  1. Не можете да създавате или пускате колекция в транзакция.
  2. Транзакциите не могат да записват в ограничена колекция
  3. Транзакциите отнемат много време за изпълнение и по някакъв начин могат да забавят производителността на базата данни.
  4. Размерът на транзакцията е ограничен до 16 MB, което изисква разделяне на всяка, която има тенденция да надвишава този размер, на по-малки транзакции.
  5. Подлагането на голям брой документи на транзакция може да окаже прекомерен натиск върху механизма на WiredTiger и тъй като разчита на възможността за моментна снимка, ще има задържане на големи неизчистени операции в паметта. Това води до някои разходи за производителност на базата данни.

Заключение

MongoDB версия 4.0 въведе поддръжката на многодокументни транзакции за набори от реплики като характеристика за подобряване на целостта и последователността на данните. Въпреки това, има много малко приложения, които биха изисквали транзакции при използване на MongoDB. Има ограничения срещу тази функция, които я правят доста малко незряла, що се отнася до концепцията за транзакциите. Например транзакциите за разделен клъстер не се поддържат и не могат да бъдат по-големи от ограничението за размер от 16MB. Моделирането на данни осигурява по-добра структура за намаляване на транзакциите във вашата база данни. Освен ако не се занимавате със специални случаи, по-добра практика ще бъде да избягвате транзакции в MongoDB.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Десериализиране на полиморфни типове с MongoDB C# драйвер

  2. Как мога да напиша агрегиране, без да надвишава максималния размер на документа?

  3. Как да видите полетата на документа в mongo shell?

  4. Свързване с бази данни MongoDB

  5. Създайте уникално поле за автоматично увеличение с мангуста