cas
(ต้องการเวอร์ชัน Workerman >= 3.3.0)
bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)
การแทนที่แบบอะตอม เปลี่ยนค่า $old_value ด้วย $new_value。
สามารถเขียนค่าได้ก็ต่อเมื่อค่าที่ตรงกับคีย์นั้นไม่ได้ถูกเปลี่ยนแปลงโดยไคลเอนต์อื่นหลังจากที่ไคลเอนต์ปัจจุบันได้ดึงค่าครั้งสุดท้ายแล้วเท่านั้น
พารามิเตอร์
$key
คีย์เวิร์ด (เช่น $global->abc, abc คือคีย์เวิร์ด)
$old_value
ค่าข้อมูลเก่า
$new_value
ค่าข้อมูลใหม่
ค่าที่คืนกลับ
คืนค่า true ถ้าการแทนที่สำเร็จ มิฉะนั้นคืนค่า false。
คำอธิบาย:
เมื่อมีการเข้าถึงตัวแปรแชร์เดียวกันจากหลายกระบวนการพร้อมกัน บางครั้งจำเป็นต้องพิจารณาปัญหาการแข่งขัน
ตัวอย่างเช่น กระบวนการ A และ B ทั้งสองเข้ามาเพิ่มสมาชิกในรายการผู้ใช้พร้อมกัน
รายการผู้ใช้ในกระบวนการ A และ B ในปัจจุบันคือ $global->user_list = array(1,2,3)
กระบวนการ A ดำเนินการโดยการเพิ่มผู้ใช้ 4 ลงในตัวแปร $global->user_list
กระบวนการ B ดำเนินการโดยการเพิ่มผู้ใช้ 5 ลงในตัวแปร $global->user_list
กระบวนการ A ตั้งค่าตัวแปรเป็น $global->user_list = array(1,2,3,4) สำเร็จ
กระบวนการ B ตั้งค่าตัวแปรเป็น $global->user_list = array(1,2,3,5) สำเร็จ
ในขณะนี้ ตัวแปรที่ตั้งค่าโดยกระบวนการ B จะทับซ้อนตัวแปรที่ตั้งค่าโดยกระบวนการ A ทำให้ข้อมูลสูญหาย
เหตุการณ์ข้างต้นเกิดขึ้นเนื่องจากการอ่านและการตั้งค่าไม่ใช่การดำเนินการแบบอะตอม จึงนำไปสู่ปัญหาการแข่งขัน
ในการแก้ไขปัญหาการแข่งขันนี้ สามารถใช้ interface การแทนที่แบบอะตอม cas
interface cas จะตรวจสอบว่าค่าที่จะเปลี่ยนแปลงนั้นมีการเปลี่ยนแปลงโดยกระบวนการอื่นก่อนที่จะเปลี่ยนค่าว่า
ถ้ามีการเปลี่ยนแปลงแล้วจะไม่แทนที่และคืนค่า 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);