المعاملات وسلامة البيانات
المعاملات وسلامة البيانات
بعض العمليات تمسّ عدّة صفوف أو جداول ويجب أن تنجح كلّها أو تفشل كلّها — لا نصفها أبدًا. تحويل المال يخصم من حساب ويُضيف لآخر؛ إن فشلت الكتابة الثانية، يجب التراجع عن الأولى. وتضمن المعاملة (transaction) سلوك الكل-أو-لا-شيء هذا.
المثال الكلاسيكي
تأمّل تحويلًا مصرفيًا. دون معاملة، يترك انهيارٌ بين التحديثين المالَ مخصومًا من حساب دون إضافته للآخر — بيانات فاسدة:
ACID باختصار
توفّر المعاملات ضمانات ACID: الذرّية (Atomicity) (الكل أو لا شيء)، والاتساق (Consistency) (من حالة صالحة إلى صالحة)، والعزل (Isolation) (المعاملات المتزامنة لا تُفسِد بعضها)، والمتانة (Durability) (البيانات المُثبَّتة تنجو من الانهيارات).
المعاملات بـ DataSource
أبسط نهج في TypeORM هو dataSource.transaction(). كل ما داخل ردّ النداء يُثبَّت معًا، أو يتراجع كلّيًا إن رُمي أي خطأ:
manager المعاملة، لا مستودعاتك. داخل ردّ النداء، يجب أن تمرّ كل القراءات والكتابات عبر manager المُمرَّر (أو مُشغّل استعلام) لتتشارك المعاملة نفسها. استدعاء مستودع محقون عادي سيعمل خارج المعاملة.
نهج QueryRunner
لتحكّم أدقّ — تثبيت/تراجع صريح، أو حين تحتاج تحرير الاتصال بنفسك — استخدم مُشغّل استعلام:
release() (استخدم كتلة finally) يُسرّب الاتصالات حتى يُستنزَف المجمّع ويتوقّف التطبيق عن الاستجابة.
أبقِ المعاملات قصيرة
الخلاصة
تجعل المعاملات تغييرات قاعدة البيانات متعدّدة الخطوات ذرّية — تُثبَّت كلّها أو تتراجع كلّها — حافظةً سلامة البيانات (ضمانات ACID). استخدم dataSource.transaction() للحالة الشائعة (اعمل عبر manager الخاص بها)، أو QueryRunner للتحكّم الصريح (حرّر دائمًا في finally). أبقِ المعاملات قصيرة وخالية من الاستدعاءات الخارجية. تاليًا: ORM مختلف، Prisma.