cas
(يتطلب إصدار Workerman >= 3.3.0)
bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)
استبدال ذري، استخدم $new_value لاستبدال $old_value.
يمكن فقط كتابة القيمة عندما لم يتم تعديل القيمة المقابلة لهذا المفتاح بواسطة عميل آخر بعد آخر قراءة للقيمة من العميل الحالي.
المعاملات
$key
القيمة المفتاحية. (على سبيل المثال $global->abc، abc هي القيمة المفتاحية)
$old_value
البيانات القديمة
$new_value
البيانات الجديدة
قيمة الإرجاع
تُرجع true في حالة النجاح في الاستبدال، وإلا تُرجع false.
الشرح:
عند التعامل مع نفس المتغير المشترك من عمليات متعددة، يجب أن تأخذ في الاعتبار أحيانًا مشكلات التزامن.
على سبيل المثال، إذا كانت العمليتان A و B تضيفان لاعبًا إلى قائمة المستخدمين في نفس الوقت.
تكون قائمة المستخدمين الحالية لكل من عمليتي A و B هي $global->user_list = array(1,2,3).
تقوم عملية A بتعديل متغير $global->user_list، وتضيف لاعبًا 4.
تقوم عملية B بتعديل متغير $global->user_list، وتضيف لاعبًا 5.
تنجح عملية A في إعداد المتغير $global->user_list = array(1,2,3,4).
تنجح عملية B في إعداد المتغير $global->user_list = array(1,2,3,5).
في هذه الحالة، ستقوم القيمة التي حددتها عملية B بت覆盖 القيمة التي حددتها عملية A، مما يؤدي إلى فقد البيانات.
السبب في ذلك هو أن القراءة والإعداد ليست عملية ذرية موحدة، مما يؤدي إلى مشاكل التزامن.
لحل مثل هذه المشكلات، يمكن استخدام واجهة استبدال الذرية cas.
قبل تغيير قيمة، ستقوم واجهة cas بالتحقق من $old_value لمعرفة ما إذا تم تغيير هذه القيمة بواسطة عمليات أخرى،
إذا كان هناك تغيير، فلن يتم الاستبدال، وسيتم إرجاع false. خلاف ذلك، سيتم الاستبدال وإرجاع true.
انظر المثال أدناه.
تنبيه:
بعض البيانات المشتركة التي يتم التغطية بشكل متزامن لا توجد بها مشكلة، مثل النظام المزاد لعرض أعلى سعر حالي لمزادات معينة، أو المخزون الحالي لمنتج معين.
المثال
$global = new GlobalData\Client('127.0.0.1:2207');
// تهيئة القائمة
$global->user_list = array(1,2,3);
// إضافة قيمة إلى user_list بشكل ذري
do
{
$old_value = $new_value = $global->user_list;
$new_value[] = 4;
}
while(!$global->cas('user_list', $old_value, $new_value));
var_export($global->user_list);