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 одновременно добавляют участника в список пользователей.
В данный момент для двух процессов пользовательский список равен $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);