cas

(Requires Workerman version >= 3.3.0)

bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)

Atomic replacement, replacing $old_value with $new_value.
The value can only be written if, after the last read by the current client, the value corresponding to this key has not been modified by other clients.

Parameters

$key

Key value. (For example, $global->abc, where abc is the key value)

$old_value

Old data

$new_value

New data

Return value

Returns true if the replacement is successful; otherwise, returns false.

Description:

When multiple processes are simultaneously operating on the same shared variable, concurrency issues may need to be considered.

For example, if processes A and B are simultaneously adding a member to a user list.
The current user list for both processes A and B is $global->user_list = array(1,2,3).
Process A modifies the $global->user_list variable, adding user 4.
Process B modifies the $global->user_list variable, adding user 5.
Process A sets the variable $global->user_list = array(1,2,3,4) successfully.
Process B sets the variable $global->user_list = array(1,2,3,5) successfully.
At this point, the variable set by process B will overwrite the variable set by process A, resulting in data loss.

The above situation occurs because reading and setting are not atomic operations, leading to concurrency issues.
To resolve such concurrency issues, the cas atomic replacement interface can be used.
Before changing a value, the cas interface will determine whether this value has been modified by other processes based on $old_value.
If it has been modified, it will not perform the replacement and return false. Otherwise, it will perform the replacement and return true.
See the example below.

Note:
Some shared data being overwritten concurrently is not an issue, such as the current highest bid for an auction item in a bidding system, or the current inventory of a product.

Example

$global = new GlobalData\Client('127.0.0.1:2207');

// Initialize list
$global->user_list = array(1,2,3);

// Atomically add a value to 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);