كيف تشعر بالمعاملات في MongoDB الآن

في صيف 2018 (أي الآن ، حتى وقت كتابة هذا التقرير) ، حدث ما لا يصدق - تم إدخال معاملات ACID الصادقة إلى MongoDB . مع إصدار الإصدار الرابع من نظام إدارة قواعد البيانات المستند إلى المستندات ، يمكن استخدامه للتطبيقات الأكثر خطورة قليلاً.


لأولئك الذين هم في الخزان ، باختصار: تسمح لنا المعاملات بإجراء سلسلة من التغييرات في العديد من المستندات وحفظها في وقت واحد ، أو أيضًا إلغاء جميع التغييرات التي تم إجراؤها داخل المعاملة بنفس الطريقة ، إذا حدث خطأ ما ، أو تعطل التطبيق .


لسوء الحظ ، المطور ليس من السهل استخدام هذه الميزة الفائقة. أدناه سأخبرك لماذا ، وماذا تفعل حيال ذلك كله.


إذا فتحنا وثائق نظام إدارة قواعد البيانات (DBMS) في قسم المعاملات ، فيمكننا رؤية الملاحظة التالية:


المعاملات متعددة المستندات متاحة لمجموعات النسخ المتماثلة فقط. تتم جدولة معاملات التجمعات الحادة في MongoDB 4.2

هذا يخبرنا أن خادم MongoDB البسيط لا يدعم المعاملات ، فقط كتلة في وضع مجموعة النسخ المتماثلة . سيأتي دعم المجموعات الحادة أيضًا لاحقًا في الإصدار 4.2.


في الوقت نفسه ، سيسمح لنا الخادم العادي ببدء معاملة أو حفظها أو إلغائها ، ولكن لا يمكن فعل أي شيء داخلها ، سيتم عرض خطأ مثل هذا:


WriteCommandError({ "ok" : 0, "errmsg" : "Transaction numbers are only allowed on a replica set member or mongos", "code" : 20, "codeName" : "IllegalOperation" }) 

لحسن الحظ ، يمكن لأي شخص تشغيل كتلة MongoDB خادم واحد. على أجهزتي ، التي أعمل عليها في التطوير ، أقوم بتشغيل جميع DBMSs في حاويات عامل ميناء . على سبيل المثال ، يبدو بدء خادم MongoDB عادي كما يلي:


 docker run -v ~/mongo/:/data/db --name mongo --restart=always -p 27017:27017 -d mongo mongod --smallfiles 

دعنا نحلل مفاتيح بدء التشغيل:


  • -v ~ / mongo /: / data / db يعني تحميل الدليل المحلي ~ / mongo / in / data / db للحاوية ، لذلك سيتم تخزين قاعدة البيانات نفسها على الجهاز المضيف ، مما سيسمح لنا بحذف الحاوية قيد التشغيل ، وتحديث الإصدارات ، وما إلى ذلك. د. مع الحفاظ على بياناتنا ؛
  • - الاسم mongo يحدد اسم الحاوية ؛
  • --restart = يقول دائمًا أنه في حالة تعطل الخدمة في الحاوية ، يجب إعادة تشغيلها ، وكذلك بدء الحاوية بعد تحميل نظام التشغيل ؛
  • -p 27017: 27017 "إعادة توجيه" المنفذ إلى الجهاز المضيف ؛
  • يشير -d إلى أنك بحاجة إلى بدء الحاوية كبرنامج خفي ؛
  • mongo - اسم الصورة لتشغيل الحاوية ؛
  • mongod --smallfiles - الأمر لبدء الخدمة في الحاوية.

كيفية بدء تشغيل خادم بسيط ، أحضرت فقط كمرجع. الآن دعونا نفهم ما يجب القيام به لبدء خادم يدعم المعاملات.


بادئ ذي بدء ، يجب عليك إنشاء شبكة جديدة داخل عامل الميناء ، حيث ستعمل جميع خوادم مجموعتنا. نعم ، لقد كتبت أعلاه أنه سيكون هناك خادم واحد ، ولكن يجب إنشاء شبكة ، وإلا فلن يعمل شيء.


 docker network create mongo-cluster 

بعد ذلك ، في معلمات تشغيل الحاوية ، تحتاج إلى تحديد استخدام الشبكة الجديدة - net mongo-الكتلة ، وكذلك تمرير المعلمة إلى الخادم للعمل في وضع مجموعة النسخ المتماثلة: --replSet rs0 . أيضا ، حذفت عمدا التبديل --restart = دائما ، كما لا أستخدم MongoDB دائمًا في العمل في الوقت الحالي ولا أريد أن يبدأ نظام التشغيل.


 docker run -v ~/mongo/:/data/db --name mongo -p 27017:27017 -d mongo mongod --smallfiles --replSet rs0 

رائع ، الحاوية تعمل ، كما يمكننا رؤيتها من خلال تشغيل الأمر docker ps ورؤية شيء مثل ما يلي:


 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2292d7e0778b mongo "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:27017->27017/tcp mongo 

بعد ذلك ، نحتاج إلى تهيئة المجموعة ، لهذا نذهب إلى وحدة التحكم الخاصة بالخادم الجاري تشغيله ، وننشئ تكوين المجموعة وننفذ التهيئة:


 docker exec -it mongo mongo # output omited # > config = { "_id" : "rs0", "members" : [ { "_id" : 0, "host" : "mongo:27017" } ] } > rs.initiate(config) { "ok" : 1, "operationTime" : Timestamp(1531248932, 1), "$clusterTime" : { "clusterTime" : Timestamp(1531248932, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } rs0:SECONDARY> rs0:PRIMARY> 

انتهى! لقد حصلنا على كتلة من خادم MongoDB واحد. الآن يمكنك التحقق من أن كل شيء يعمل كما هو متوقع.


 rs0:PRIMARY> session = db.getMongo().startSession() session { "id" : UUID("7eb81006-983f-4398-adc7-5ed23e027377") } rs0:PRIMARY> database = session.getDatabase("test") test rs0:PRIMARY> //    rs0:PRIMARY> database.col.insert({name: "1"}) WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> database.col.insert({name: "2"}) WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> database.col.insert({name: "3"}) WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> database.col.insert({name: "4"}) WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> // ,     rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "1" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "4" } rs0:PRIMARY> //   rs0:PRIMARY> session.startTransaction() rs0:PRIMARY> //    rs0:PRIMARY> database.col.update({name: "4"}, {name: "44"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) rs0:PRIMARY> //   rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "1" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "44" } rs0:PRIMARY> //         ,    -: rs0:PRIMARY> // { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "4" } rs0:PRIMARY> //   rs0:PRIMARY> session.commitTransaction() rs0:PRIMARY> //   rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "1" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "44" } rs0:PRIMARY> //     rs0:PRIMARY> session.startTransaction() rs0:PRIMARY> database.col.update({name: "44"}, {name: "42"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "1" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "42" } rs0:PRIMARY> database.col.update({name: "1"}, {name: "21"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "21" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "42" } rs0:PRIMARY> session.commitTransaction() rs0:PRIMARY> //   rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "21" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "42" } rs0:PRIMARY> //   ,     rs0:PRIMARY> session.startTransaction() rs0:PRIMARY> database.col.update({name: "21"}, {name: "1"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "1" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "42" } rs0:PRIMARY> //   rs0:PRIMARY> session.abortTransaction() rs0:PRIMARY> database.col.find({}) { "_id" : ObjectId("5b45026edc396f534f11952f"), "name" : "21" } { "_id" : ObjectId("5b450272dc396f534f119530"), "name" : "2" } { "_id" : ObjectId("5b450274dc396f534f119531"), "name" : "3" } { "_id" : ObjectId("5b450276dc396f534f119532"), "name" : "42" } rs0:PRIMARY> // !     ! rs0:PRIMARY> 

وبالتالي ، بدون إجهاد ، يمكنك تجربة معاملات مونغ الآن دون بدء مجموعة متعددة الخوادم. أنصحك بالاطلاع على الوثائق وقراءة قيود المعاملات. على سبيل المثال ، تلك المعاملات "مباشرة" لمدة لا تزيد عن دقيقة واحدة ، إذا لم تتمكن من حفظ التغييرات ، فسيتم إلغاؤها.


ملاحظة: الغرض من هذه المقالة ليس لتعليمك كيفية استخدام عامل الميناء أو العمل مع monga ، ولكن فقط طريقة سريعة لتجربة أدوات جديدة من DBMS المثير للاهتمام.

Source: https://habr.com/ru/post/ar417131/


All Articles