كيف كاد السبات أن يدمر حياتي المهنية
نشرت: 2022-03-11تخيل أنك مطور Java ، وأنت على وشك بدء مشروعك الكبير التالي. أنت بحاجة إلى اتخاذ القرارات الأساسية التي ستلتزم بك لبقية المشروع. تريد اختيار أفضل تجريد كائني المنحى لنموذج بياناتك المرن لأنك لا تريد التعامل مع SQL عادي. تريد دعم جميع أنواع البيانات ، وبشكل مثالي ، دعم جميع أنواع قواعد البيانات.
الجواب الواضح هو استخدام وضع السبات فقط ، أليس كذلك؟ سيوافقك 90٪ من مطوري Java ، لكن هل هذا يجعله القرار الصحيح؟
دعنا نلقي نظرة على الخطأ الذي يمكن أن يحدث إذا استخدمت Hibernate بشكل أعمى لمجرد أنه المعيار المقبول.
لنأخذ على سبيل المثال مونيكا ، مطور جافا. تمت ترقية مونيكا مؤخرًا إلى دور مهندسة معمارية وهي الآن مسؤولة عن وضع مجموعة التكنولوجيا لمنتج جديد في شركتها. إنها تعلم أنه في عالم Java لا يوجد سوى أداة جيدة واحدة للتعامل مع اتصالات قاعدة البيانات: Hibernate . الإسبات هو معيار JPA معروف ومعتمد. ومع ذلك ، من الجيد دائمًا التحقق من بعض الأشياء قبل بدء المشروع. لحسن الحظ ، يعرف زميلها بن الرجل المناسب.
يبدو السبات وكأنه رصاصة فضية
بن - مرحبا مونيكا ، أود أن أقدم جون. إنه خبير في السبات ، وسيساعدك.
مونيكا - مرحبًا جون ، سعيد لأنك وجدت لي بعض الوقت. لذا ، نحن نبني الشيء الكبير التالي ، كما تعلمون. نحن نخطط لأن نصبح Facebook أو Google التاليين. أيام مشغولة. ستكون ضخمة. مذهل! الجميع متحمس جدا! لقد تمت ترقيتي إلى دور مهندس معماري ، لذا يتعين علي الآن تحديد المكدس الذي سنستخدمه. الجزء الوحيد المفقود هو المثابرة ...
جون - السبات !
مونيكا - نعم! بالضبط! فقط ما كنت أفكر فيه! يبدو أنها مباراة مثالية وصفقة حقيقية بالنسبة لنا. حل مؤسسي حقيقي لمشكلة مؤسسة حقيقية ، أثبته السوق وله تاريخ طويل. لقد سمعت الكثير من التجارب الإيجابية معها. ومع ذلك ، لدي مشكلة مع أحد زملائنا في الفريق ؛ إنه ضدها تمامًا. إنه يعرف الكثير عن قواعد البيانات ، ويخشى إضافة طبقة أخرى بين تطبيقنا وقاعدة البيانات. إنه ذكي للغاية ، وأحتاج إلى بعض الحجج الجيدة حقًا لإقناعه بأن هذا قرار جيد. هل يمكنك مساعدتي مع هذا؟
جون - بالطبع! سأكون سعيدا ل. في الواقع ، يعد السبات أداة رائعة. يتم استخدامه على نطاق واسع في حلول المؤسسات الكبيرة والحقيقية ، مثل البنوك. لا يمكنك أن تخطئ في ذلك. فكر في المثابرة: اختر السبات . إذا كنت تكتب بلغة Java ، فهذا هو الخيار الصحيح تمامًا ، بالإضافة إلى أن لديك منافذ للغات أخرى. تعرف على عدد الأوصاف الوظيفية التي تتطلب ذلك!
مونيكا - أوافق تمامًا! لدي نفس المشاعر حيال ذلك. في مشروع سابق ، كنا نستخدم SQL في الغالب عبر JDBC القديم. سخيف! أنا أعرف! ولكن ، هذا هو الشيء: لدينا رجال SQL أذكياء حقًا في الفريق وعندما رأوا SQL تم إنشاؤه بواسطة Hibernate ، شعروا بالتوتر. بدا الأمر قبيحًا وغير قابل للقراءة. هل ستكون هذه مشكلة في المستقبل؟
جون - انظر. الرجال DBA لديهم منظور مختلف. إنهم خائفون من السبات لأنه يبدو أنه يحل محل دورهم في المشروع. علاوة على ذلك ، تحتوي قواعد البيانات على أدوات تحسين استعلام مضمنة ، لذا لا داعي للقلق بشأن الشكل الذي ستبدو عليه هذه الاستعلامات بالفعل. ستعمل قاعدة البيانات على تحسينها لك. الأمر كله يتعلق بالتطور السريع ، الذي لا تستطيع SQL القيام به.
مونيكا - حقا ؟! لم تعد تتعامل مع SQL؟ مدهش! آخر مرة قضى DBA أسابيع في محاولة تحسين بعض الاستفسارات. أسابيع! أوه ، أشعر بالحرج الشديد عندما أخبرك بهذا ، لكن هل تعلم أننا كنا نستخدم ... إجراءات مخزنة (يضحك). أوه ، لقد كانت مثل هذه الفوضى. هل تصدق أن المشروع لا يزال يستخدمه؟ أشعر بالأسف الشديد للناس هناك. لا يزال يتعين عليهم كتابة هذا الرمز المملة مرارًا وتكرارًا. أتساءل ما إذا كان لا يزال مشروع Java أو SQL؟
جون - هذا هو بالضبط الفرق بين النهج الموجه للكائنات والأسلوب العلائقي. إنه ما يسمى عدم تطابق المعاوقة الشيئية. يمكن أن يسد السبات هذه الفجوة. يمكن للمطورين التركيز على بناء منطق الأعمال. ميزات الدفع تجعل أصحاب المصلحة والإدارة بأكملها سعداء. افعل الأشياء الأكثر أهمية: الأعمال! ستختفي الكثير من الشفرات المعيارية ، وسيكون لديك اتصال سحري ، غير مرئي ، لكنه موثوق ، بين المنطق والبيانات.
مونيكا - التعاون المتبادل. التآزر الكامل. مثل قاعدة البيانات كانت جزءًا من اللغة منذ البداية. أنا سعيد جدًا لأنني أصبحت قائدًا لهذه القفزة التكنولوجية في الإيمان. إنها مثل سرعة الالتواء في رحلة البرنامج.
جون - نعم! لقد حصلت عليها!
مونيكا - يا إلهي ، أنا متحمس جدًا! شكرا لك جون! أنا مستعد!
تزايد الآلام مع الحلول غير المرنة
مونيكا - مرحبًا جون ، هل تتذكر المشروع الذي تحدثنا عنه العام الماضي؟
جون - بالتأكيد. كيف تجري الامور؟
مونيكا - سنبدأ الإنتاج قريبًا. كل شيء على ما يرام ، ولكن ظهرت بعض الأسئلة.
جون - بالتأكيد ، اضربني.
مونيكا - حسنًا ، لم يعد بإمكاننا إنشاء مخطط قاعدة البيانات من البداية. ما هي أفضل طريقة لدعم تغييرات المخطط دون فقدان البيانات؟
جون - حسنًا ، أولاً ، لا يُقصد استخدام Hibernate كأداة لترحيل الإنتاج. استخدم شيئًا مثل FlywayDB أو Liquibase. انها بسيطة جدا. تقوم بتدوين البرامج النصية للترحيل ، ثم تقوم بتحديث نموذج الكيان مع تعيينات Hibernate ، بحيث تظل متزامنة مع بنية قاعدة البيانات الفعلية.
مونيكا - حسنًا ، فهمت. كنا نستخدم فقط ترحيل SQL عادي في المشروع السابق.
جون - هذا جيد أيضًا. طالما تحافظ على مزامنة نموذج الكيان والمخطط ، افعل ذلك بالطريقة التي تريدها.
مونيكا - فهمت. هناك شيء آخر. نحن نكافح دائمًا مع مشاكل الجلب البطيئة / المتلهفة. في مرحلة ما ، قررنا أن نفعل كل شيء بلهفة ، لكن يبدو أنه دون المستوى الأمثل ، وإلى جانب ذلك ، في بعض الأحيان لا يمكن الوصول إلى بعض الحقول لأنه لا توجد جلسة ، أو شيء من هذا القبيل. غير أن وضعها الطبيعي؟
جون - أنت بحاجة لمعرفة المزيد عن السبات . التعيين من قاعدة البيانات ليس مباشرًا. في الأساس ، هناك طرق متعددة للقيام بذلك. ما عليك سوى اختيار الطريقة التي تناسبك. يمنحك الجلب الكسول القدرة على تحميل تلك الأشياء عند الطلب ، لكنك تحتاج إلى العمل في جلسة نشطة.
مونيكا - ما زلنا نكافح مع تحديد محرك قاعدة البيانات الذي يجب استخدامه للنشر النهائي. اعتقدت أن Hibernate كان محمولًا ، لكن لدينا بعض الاستعلامات الأصلية التي تستخدم سحر MS SQL ، ونود بالفعل استخدام MySQL في الإنتاج.
John - Hibernate يمنحك المرونة طالما أنك تستخدم معايير منفصلة أو HQL ؛ ستعمل أي استعلامات أصلية على ربط الحل الخاص بك بقاعدة البيانات.
مونيكا - يبدو أنه يتعين علينا التمسك بـ MS SQL بعد ذلك. السؤال الأخير: قال زميلي في الفريق إنه لا توجد كلمة رئيسية "محدودة" في HQL. اعتقدت أنه كان يمزح ، لكنني لم أجدها أيضًا. آسف للسؤال غبي…
جون - في الواقع ، لا توجد كلمة رئيسية "حد" في HQL. يمكنك التحكم في هذا من خلال كائن الاستعلام لأنه قاعدة بيانات خاصة ببائع.
مونيكا - يبدو غريبًا أن جميع العناصر الأخرى موجودة في HQL. لا يهم. شكرا على وقتك!
نحن الآن نبدأ معًا في اختراق حلول SQL مرة أخرى
مونيكا - جون ، في البداية لم نكن نتعامل مع SQL ، ولكن يبدو الآن أنه يتعين علينا ذلك. احتياجاتنا آخذة في الازدياد ، ويبدو أنه لا توجد طريقة للتغلب عليها. إنه شعور خاطئ ، لكننا بدأنا في استخدام SQL مرة أخرى على أساس يومي.

جون - حسنًا ، هذا ليس خطأ. لم يكن عليك التركيز على قاعدة البيانات في البداية. ومع ذلك ، مع نمو المشروع ، من الجيد استخدام SQL والعمل على تحسين الأداء.
مونيكا - نقضي أحيانًا أيامًا في البحث عن الأخطاء. يبدو أنه يتعين علينا تحليل SQL المولدة في Hibernate لأننا لا نملك أي فكرة عن سبب عدم عملها بالشكل المتوقع وإنها تؤدي إلى نتائج غير متوقعة. لقد واجهنا بعض المشكلات المعروفة جيدًا في متتبع أخطاء الإسبات . بالإضافة إلى ذلك ، من الصعب كتابة عمليات الترحيل المناسبة مع الحفاظ على مزامنة نموذج الكيان. يستغرق الأمر وقتًا طويلاً نظرًا لأننا بحاجة إلى معرفة الكثير عن الأجزاء الداخلية للإسبات والتنبؤ بكيفية عملها.
جون - هناك دائمًا منحنى تعليمي. ليس عليك أن تكتب كثيرًا ، لكن عليك أن تعرف كيف تعمل.
مونيكا - العمل مع مجموعات بيانات أكبر أمر مزعج أيضًا. في الآونة الأخيرة ، قمنا باستيراد ضخم لقاعدة البيانات ، وكان ذلك بطيئًا بشكل مؤلم. ثم اكتشفنا أنه كان علينا مسح الجلسة لجعلها أسرع. ومع ذلك ، فإنه لا يزال أبطأ بشكل ملحوظ ، لذلك قررنا إعادة كتابته على هيئة عبارات SQL عادية. الأمر المضحك هو أن كتابة SQL كانت في الواقع أسرع طريقة للقيام بذلك ، لذلك قررنا القيام بذلك كخيارنا الأخير.
جون - الاستيراد ليس عملية كائنية التوجه. يركز Hibernate على التصميم الموجه للكائنات. تذكر أنه يمكنك دائمًا استخدام الاستعلامات المحلية.
مونيكا - هل يمكنك مساعدتي في فهم كيفية عمل ذاكرة التخزين المؤقت للإسبات ؟ أنا فقط لا تحصل عليه. هناك بعض مخابئ المستوى الأول / الثاني. حول ماذا يدور كل هذا؟
جون - بالتأكيد. إنها ذاكرة تخزين مؤقت للبيانات الدائمة على مستوى المعاملات. من الممكن تكوين مجموعة أو ذاكرة تخزين مؤقت على مستوى JVM على أساس فئة تلو فئة وأساس مجموعة تلو الأخرى. يمكنك حتى توصيل ذاكرة تخزين مؤقت مجمعة. لكن تذكر أن ذاكرات التخزين المؤقت ليست على علم بأي تغييرات تم إجراؤها على المخزن الدائم بواسطة تطبيق آخر. ومع ذلك ، يمكن تهيئتها لحذف البيانات المخزنة مؤقتًا منتهية الصلاحية بانتظام.
مونيكا - آسف ، أعتقد أنني أمضي يومًا سيئًا. هل يمكنك شرح هذا قليلا؟
جون - بالتأكيد. عندما تقوم بتمرير كائن save أو update أو saveOrUpdate أو تحديثه أو استرداده عن طريق load أو get أو list أو iterate أو scroll ، تتم إضافة هذا الكائن إلى ذاكرة التخزين المؤقت الداخلية للجلسة. يمكنك أيضًا إزالة الكائن ومجموعاته من ذاكرة التخزين المؤقت للمستوى الأول.
مونيكا - إيه ...
جون - بالإضافة إلى ذلك ، يمكنك التحكم في أوضاع التخزين المؤقت. يمكنك استخدام الوضع normal لقراءة العناصر وكتابتها في ذاكرة التخزين المؤقت من المستوى الثاني. استخدم get Get للقراءة من المستوى الثاني ولكن لا يمكنك إعادة الكتابة. استخدم put ، وهو نفس الشيء مثل get ولكن لا يمكنك القراءة من المستوى الثاني. يمكنك أيضًا استخدام وضع refresh ، والذي سينتقل إلى المستوى الثاني ، ولكن لا يقرأ منه ويتجاوز خاصية use minimal puts من الوضعيات ، مما يفرض تحديثًا لذاكرة التخزين المؤقت من المستوى الثاني لجميع العناصر المقروءة من قاعدة البيانات.
مونيكا - فهمت. نعم. دعني أفكر في هذا. أوه ، لقد فات الوقت ، علي أن أذهب. شكرا على وقتك!
جون - على الرحب والسعة!
التخلي عن السبات
مونيكا - جون ، اعتقدت أننا ندخل حقبة جديدة من تطوير البرمجيات. اعتقدت أننا كنا نقوم بقفزة سنة ضوئية. ولكن بعد أربع سنوات ، يبدو أننا ما زلنا نتعامل مع جميع المشكلات نفسها ، ولكن من زاوية مختلفة فقط. كان علي أن أتعلم بنية Hibernate ، والتكوين ، والتسجيل ، واستراتيجيات التسمية ، و tuplizers ، ومحللات اسم الكيان ، ومولدات المعرف المحسّنة ، وتحسين مولد المعرف ، والفئات الفرعية النقابية ، و XDoclet ، والجمعيات ثنائية الاتجاه مع المجموعات المفهرسة ، والجمعيات الثلاثية ، وحقيبة الهوية ، وخلط تعدد الأشكال الضمني مع تعيينات الوراثة الأخرى ، تكرار الكائن بين اثنين من مخازن البيانات المختلفة ، والكائنات المنفصلة والإصدار التلقائي ، وأنماط تحرير الاتصال ، وواجهة الجلسة عديمة الحالة ، وتصنيف استمرارية المجموعة ، ومستويات ذاكرة التخزين المؤقت ، والجلب البطيء أو النشط وغير ذلك الكثير. حتى مع كل ما أعرفه ، يبدو أننا فشلنا بشدة. إنه إخفاق في البرامج! فشل نهائي! كارثة! الكارثة!
جون - انتظر! ماذا حدث؟
مونيكا - لقد وصلنا إلى طريق مسدود. أداء التطبيق لدينا بطيء بشكل يبعث على السخرية! للحصول على تقرير ، علينا الانتظار يومين! يومان لإنشاء لوحة تحكم للعميل بالفعل. هذا يعني أنه يتعين علينا كل يوم زيادة ذيل حساباتنا ، بينما تصبح لوحة القيادة الخاصة بنا قديمة أكثر فأكثر. يعمل خبير DBA لمدة شهرين لتحسين بعض الاستعلامات ، في حين أن بنية قاعدة البيانات لدينا عبارة عن فوضى كاملة. هناك مطورون يدعمونه ، لكن المشكلة هي أن DBA يفكر في SQL ، ويقضي المطورون أيامًا في محاولة ترجمة هذا إلى معايير منفصلة أو تنسيق HQL. نحن نحاول استخدام SQL الأصلي قدر الإمكان لأن الأداء أمر بالغ الأهمية في الوقت الحالي. على أي حال ، لا يمكننا فعل الكثير لأن مخطط قاعدة البيانات يبدو خاطئًا. لقد شعرت بأنها صحيحة من منظور وجوه المنحى ، لكنها تبدو سخيفة من المنظور العلائقي. أسأل نفسي: كيف حدث هذا؟ يخبرنا المطورون أن تغيير هيكل الكيانات سيكون جهدًا هائلاً ، لذلك لا يمكننا تحمل ذلك. أتذكر في المشروع السابق أنها كانت في حالة من الفوضى ، لكننا لم ننتهي في مثل هذه المرحلة الحرجة. تمكنا من كتابة تطبيق مختلف تمامًا للعمل مع البيانات. الآن ، من الخطر تعديل تلك الجداول التي تم إنشاؤها لأنه من الصعب حقًا التأكد من أن نموذج الكيان سيتصرف دائمًا بشكل صحيح. وهذا ليس أسوأ جزء! لزيادة الأداء ، يتعين علينا ليس فقط حل مشكلات قاعدة البيانات ، ولكن أيضًا المشكلات المتعلقة بالطبقة بأكملها بين قاعدة البيانات الخاصة بنا والتطبيق. إنه أمر ساحق! لدينا هؤلاء الرجال الجدد ، كما تعلمون ، مستشارون. إنهم يحاولون استخراج البيانات ووضعها في مساحة تخزين أخرى ثم إجراء العمليات الحسابية من الخارج. الأمر كله يستغرق الكثير من الوقت!
جون - لا أعرف ماذا أقول.
مونيكا - ترى جون ؛ لا أريد أن ألومك. اخترت Hibernate لحل كل هذه المشاكل ، لكنني تعلمت الآن أنها ليست رصاصة فضية. لقد وقع الضرر ولا رجوع فيه. في الواقع ، أود أن أسألك شيئًا: لقد أمضيت السنوات الأربع الأخيرة من حياتي المهنية أتعامل مع أشياء في حالة السبات . يبدو أنه ليس لدي مستقبل في شركتي الحالية. هل بإمكانك مساعدتي؟
إذن ما هو الدرس المستفاد؟
جون - مرحبًا ، بيتر ، دعني أقدم مونيكا.
بيتر - مرحبًا مونيكا! نحن نبني الشيء الكبير التالي الجديد الذي تعرفه. ستكون ضخمة! نريد أن نكون مثل أوبر! هل تعرف ربما كيف المثابرة ...
مونيكا - ليس السبات !
يتم إحتوائه
مونيكا خبيرة في السبات . ومع ذلك ، كان الإسبات في هذه الحالة قرارًا خاطئًا. في اللحظة التي اكتشفت فيها أن الحل الذي قدمته تحول إلى مشكلة أكبر من الحل الأصلي ، كان يمثل أكبر تهديد للمشروع بأكمله.
البيانات هي الغرض المركزي للتطبيق ، سواء أعجبك ذلك أم لا ، فهو يؤثر على البنية بأكملها. كما تعلمنا من القصة ، لا تستخدم Hibernate لمجرد أن تطبيق Java الخاص بك يستخدم قاعدة بيانات أو بسبب دليل اجتماعي. اختر حلاً يتسم بالمرونة. هناك الكثير من الخيارات لأغلفة JDBC القوية ، مثل JdbcTemplate أو Fluent JDBC Wrapper. بدلاً من ذلك ، هناك حلول قوية أخرى ، مثل jOOQ.
