سؤال

وأنا باستخدام SQLAlchemy مثل ORM ضمن تطبيق لقد تم بناء لبعض الوقت.

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

وكل شيء يعمل بشكل جيد جدا حتى اختبرته في بيئة تحجيمها. لقد استعملت ك InnoDB مستوى الصف تأمين لضمان كل صف للقراءة مرة واحدة فقط، في حين يتم تأمين صف واحد، I تحديث ل'<م> in_use ' قيمة، للتأكد من أن الآخرين لا استيلاء على دخول .

ومنذ ماي لا تقدم طريقة "NOWAIT" مثل Postgre أو أوراكل لا، لقد واجهت قضايا تأمين حيث المواضيع عامل شنق والانتظار للصف مقفل لتصبح متاحة.

في محاولة للتغلب على هذا القيد، لقد حاولت أن تضع كل المعالجة المطلوبة في بيان واحد، وتشغيله من خلال مكتب إدارة السجلات في execute() طريقة، على الرغم من SQLAlchemy يرفض العودة لل نتيجة الاستعلام.

وهنا مثال على ذلك.

وبيان SQL بلادي:

SELECT id INTO @update_id FROM myTable WHERE in_use=0 ORDER BY id LIMIT 1 FOR UPDATE;
UPDATE myTable SET in_use=1 WHERE id=@update_id;
SELECT * FROM myTable WHERE id=@update_id;

وتشغيل هذه التعليمات البرمجية في وحدة التحكم:

engine = create_engine('mysql://<user details>@<server details>/myDatabase', pool_recycle=90, echo=True)
result = engine.execute(sqlStatement)
result.fetchall()

وفقط للحصول على هذه النتيجة

[]

وأنا واثق من البيان تشغيل منذ أستطيع أن أرى تأثير التحديث تأخذ في قاعدة البيانات، وإذا كنت تنفيذ عبر معبر الخلية أو غيرها من الأدوات، وأحصل على إرجاع الصف تعديلها. هو فقط يبدو أن SQLAlchemy لا نريد أن نعترف الصف إرجاعها.

هل هناك أي شيء محدد لا بد من القيام به لضمان أن ORM تلتقط الرد؟

وهتاف

هل كانت مفيدة؟

المحلول

ولقد أعدم 3 الاستفسارات وMySQLdb يخلق نتيجة تعيين لكل منها. لديك لجلب النتيجة الأولى، ثم استدعاء cursor.nextset()، جلب الثانية وهلم جرا.

وهذا يجيب عن سؤالك، ولكن لن يكون من المفيد بالنسبة لك، لأنه لن يحل قفل القضية. عليك أن تفهم كيف يعمل FOR UPDATE أولا: تستقر عاد الصفوف حتى نهاية المعاملة. لتجنب طويلة قفل الانتظار لديك لجعلها قصيرة قدر الإمكان: SELECT ... FOR UPDATE، UPDATE SET in_use=1 ...، COMMIT. كنت في الواقع لا تحتاج لوضعها في بيان SQL واحد، وسوف 3 المكالمات execute() على ما يرام أيضا. ولكن عليك أن ارتكاب قبل حساب طويل، وإلا قفل سيعقد طويلة جدا وتحديث in_use (حاليا تأمين) لا معنى له. وتأكد من أنك تستطيع أن تفعل نفس الشيء باستخدام ORM أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top