سؤال

لقد أنشأنا طبقة مخزئة للتخزين المؤقت لتطبيق J2EE الخاص بنا. في هذه الحالة نستخدم EHCACHE. وقد أنشأ هذا بعض التحديات.

دعونا نأخذ هذا المثال.

OrderItem orderitem = cache.getOrderItemByID("id");
OrderItem old_orderitem = cache.getOrderItemID("id");

orderitem.setStatus(1);
old_orderitem.setStatus(2);

إذا كنا لا نحرص، فإن أي تغييرات تم إجراؤها على أي من هذه الكائنات ستؤثر على الآخر (يشيرون إلى نفس الكائن). إنقاذ الطلب مرة أخرى إلى dabase سيجعله الوضع = 2

كيف نحل هذه أفضل طريقة؟

لقد حاولنا إنشاء طريقة .COPYOBJECT () لكل كائن. الذي ينشئ فقط كائن جديد ويقوم بتعيين جميع القيم. ولكن هذا لا يبدو وكأنه حل جيد.

المثال كان فقط للتوضيح. الرمز هو أكثر تعقيدا بكثير من ذلك، ولكن النتيجة هي نفسها.

********************** تحديث 15.07.2010 ************************ **************************

في EHCACHACHE 2 هناك بعض الخيارات لتشغيل CopyRead () وكتابة نسخ (). وهذا يحل كل مشاكلي :)

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

المحلول

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

HashMap map = new HashMap();
map.put("one", new OrderItem());
OrderItem one = map.get("one");
OrderItem two = map.get("one");
one.setStatus(1);
two.setStatus(2);

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

أنت على حق في النظر في نسخ الكائن. خياراتك هي:

لكل منها نقاط القوة والضعف لها والتي تعمل بشكل أفضل على بيئتك.

نصائح أخرى

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

إذا كانت هذه هي الحالة، فإن طبقة الكاشطات المخصصة الخاصة بك (حول EHCACHE) تحتاج إلى إنشاء كائن من بيانات ذاكرة التخزين المؤقت عندما يقوم المستخدم بطلب طلب - سيمنحك هذا كائلا فريدا في كل مرة ولن تحصل على تداخل كائن.

عند استرداد ذاكرة التخزين المؤقت بواسطة المعرف (GetOUstritembyID)، أفترض أن يعني "الحصول على الكائن فريد تم تحديده بواسطة ID =؟ ". في مقتطفاتك الثانية لديك (أو تحاول أن يكون لديك؟) 2 كائنات مختلفة لذلك يبدو أنك تحاول القيام بأشياء متناقضة في الكود.

يمكنك تطبيق تفرد ID = "ID" هو دائما نفس الكائن. إذا قمت بتعيين الحالة ثم إعادة تعيينه، فهذا يعني أن الكائن نفسه يحتوي على حالة جديدة. من المحتمل أنك تريد تمديد طريقة. المساواة للعودة إلى TRUE إذا كان معرف المطابقات كذلك.

يمكنك أيضا استخدام علامة "قذرة" لتمييز الكائنات التي تم تغييرها من مخزن البيانات (المعاملات؟).

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

ما هو السلوك المناسب للتطبيق الخاص بك؟

يوفر EHCACHACHE دعم لقفل مفاتيح عبر API قفل صريح. يمكنك قفل على المفتاح في ذاكرة التخزين المؤقت مع أقفال القراءة والكتابة. هذا لا يقلق على القيمة في ذاكرة التخزين المؤقت، لذلك لا يزال الكائن مفتوحا على الطفرات إذا قرر المبرمج.

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

ومع ذلك، فإن مشكلة حالة قابلة للتغيير، كما يذكر جيمي ماككرينل، لا يذهب بعيدا.

المرجعي: http://ehcache.org/documentation/explicitLocking.html.

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