سؤال

ودعونا نقول لدي وظيفة العداد الذي بتحديث عداد باستخدام SQL الخام:

 public void updateCounter() {
   executeSql("UPDATE counter SET count_value = count_value + 1 WHERE id = 1;");
 }

وقاعدة بيانات من شأنها أن تجعل من أن يتم التعامل مع مكالمتين المتزامنة إلى العداد كما هو متوقع - أن جميع المكالمات سوف تقوم بتحديث العداد مع زيادة واحدة، وسوف تضيع أية تحديثات

وبدلا من تنفيذ ذلك عن طريق إصدار أمر SQL الخام أود أن استخدام GORM. طريقة ساذجة للقيام بذلك سيكون شيئا على غرار:

 public void updateCounter() {
   Counter c = Counter.get(1)
   c.countValue += 1
   c.save()
 }

في هذه الحالة يهمني ان نفترض ان تحديثا يمكن أن تضيع إذا كان اثنان المواضيع استدعاء الأسلوب updateCounter () في نفس اللحظة. ما هو الصحيح "الكؤوس المقدسة / GORM في اتجاه" للتعامل مع هذه المسألة التزامن؟

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

المحلول

هل يمكن استخدام إما "متشائمة" أو "متفائلة" تأمين الاستراتيجيات، وكلاهما بدعم من السبات، وبالتالي كتبها GORM. استراتيجية GORM الافتراضية هي "متفائلة" (الذي يستخدم نسخة العمود / ملكا للكيان مجال المستمر، التي أنشأتها الافتراضي). ويمكن استخدام مثل هذا:

...
try {
 Counter c = Counter.get(1)
 c.countValue += 1
 c.save(flush:true)
}
catch(org.springframework.dao.OptimisticLockingFailureException e) {
// deal with concurrent modification here
}
...

إذا كنت تفضل استراتيجية "متشائمة" قفل بدلا (والتي من شأنها عرقلة كل المتزامنة الآخر يقرأ، راجع للشغل)، هل يمكن أن تفعل ذلك باستخدام صريح "قفل" GORM الفوقية الطريقة، كما يلي:

...
Counter c = Counter.lock(1) //lock the entire row for update
c.countValue += 1
c.save(flush:true) //GORM will autorelease the lock once the TX is committed
...

وآمل أن يساعد هذا.

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