cas

(requer Workerman versão >= 3.3.0)

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

Substituição atômica, onde$new_value substitui$old_value.
Somente pode-se escrever o valor se, após a última leitura feita pelo cliente atual, o valor correspondente a essa chave não tiver sido modificado por outros clientes.

Parâmetros

$key

Chave. (por exemplo$global->abcabc é a chave)

$old_value

Valor antigo

$new_value

Novo valor

Valor de retorno

Retorna true se a substituição for bem-sucedida, caso contrário, retorna false.

Descrição:

Quando múltiplos processos operam simultaneamente em uma mesma variável compartilhada, às vezes é necessário considerar problemas de concorrência.

Por exemplo, os processos A e B estão simultaneamente adicionando um membro à lista de usuários.
A e B atualmente possuem a lista de usuários como$global->user_list = array(1,2,3).
O processo A modifica a variável$global->user_list para adicionar um usuário 4.
O processo B modifica a variável$global->user_list para adicionar um usuário 5.
O processo A define a variável$global->user_list = array(1,2,3,4) com sucesso.
O processo B define a variável$global->user_list = array(1,2,3,5) com sucesso.
Neste momento, a variável definida pelo processo B sobrepõe a variável definida pelo processo A, resultando em perda de dados.

O acima ocorre porque a leitura e a definição não são operações atômicas, levando a problemas de concorrência.
Para resolver esse tipo de problema de concorrência, pode-se usar a interface de substituição atômica cas.
A interface cas, antes de alterar um valor,
verifica se o valor foi modificado por outros processos com base em$old_value.
Se houve alteração, não substitui e retorna false. Caso contrário, substitui e retorna true.
Veja o exemplo abaixo.

Atenção:
Em alguns dados compartilhados, a sobreposição concorrente não é um problema, como, por exemplo, o maior lance atual em um sistema de leilão ou o estoque atual de um produto.

Exemplo

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

// Inicializa a lista
$global->user_list = array(1,2,3);

// Adiciona um valor à user_list de forma atômica
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);