cas
(yêu cầu phiên bản Workerman >= 3.3.0)
bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)
Thay thế nguyên tử, dùng $new_value để thay thế cho $old_value.
Chỉ trong trường hợp giá trị tương ứng với key này không bị thay đổi bởi các client khác sau lần lấy giá trị cuối cùng của client hiện tại, giá trị mới mới có thể được ghi vào.
Tham số
$key
Giá trị khóa. (ví dụ $global->abc , abc là giá trị khóa)
$old_value
Dữ liệu cũ
$new_value
Dữ liệu mới
Giá trị trả về
Trả về true nếu thay thế thành công, nếu không trả về false.
Giải thích:
Khi nhiều tiến trình cùng thao tác trên một biến chia sẻ, đôi khi cần xem xét vấn đề đồng thời.
Ví dụ, hai tiến trình A và B cùng thêm một thành viên vào danh sách người dùng.
Danh sách người dùng hiện tại của cả hai tiến trình A và B đều là $global->user_list = array(1,2,3).
Tiến trình A thao tác biến $global->user_list, thêm một người dùng 4.
Tiến trình B thao tác biến $global->user_list, tăng một người dùng 5.
Tiến trình A đặt biến $global->user_list = array(1,2,3,4) thành công.
Tiến trình B đặt biến $global->user_list = array(1,2,3,5) thành công.
Lúc này biến được thiết lập bởi tiến trình B sẽ ghi đè lên biến thiết lập bởi tiến trình A, dẫn đến mất dữ liệu.
Điều này xảy ra do việc đọc và thiết lập không phải là một thao tác nguyên tử, dẫn đến vấn đề đồng thời.
Để giải quyết vấn đề đồng thời này, có thể sử dụng giao diện thay thế nguyên tử cas.
Giao diện cas sẽ kiểm tra xem giá trị có được các tiến trình khác thay đổi hay không trước khi thay đổi một giá trị,
nếu có thay đổi, sẽ không thay thế và trả về false. Ngược lại, nếu không có thay đổi, sẽ thay thế và trả về true.
Xem ví dụ bên dưới.
Lưu ý:
Một số dữ liệu chia sẻ bị ghi đè đồng thời là không vấn đề, chẳng hạn như giá thầu tối đa hiện tại của một món hàng trong hệ thống đấu giá, hoặc lượng tồn kho hiện tại của một sản phẩm.
Ví dụ
$global = new GlobalData\Client('127.0.0.1:2207');
// Khởi tạo danh sách
$global->user_list = array(1,2,3);
// Thêm một giá trị vào user_list nguyên tử
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);