cas

(version de Workerman requise >= 3.3.0)

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

Remplacement atomique, remplace $old_value par $new_value.
Peut écrire la valeur uniquement si la valeur correspondante à la clé n'a pas été modifiée par d'autres clients depuis la dernière lecture effectuée par le client actuel.

Paramètres

$key

Clé. (par exemple $global->abc, abc est la clé)

$old_value

Ancienne donnée

$new_value

Nouvelle donnée

Valeur de retour

Retourne true si le remplacement est réussi, sinon retourne false.

Remarque :

Lorsqu'il y a plusieurs processus opérant sur la même variable partagée, il est parfois nécessaire de prendre en compte les problèmes de concurrence.

Par exemple, les processus A et B ajoutent simultanément un membre à la liste des utilisateurs.
La liste des utilisateurs actuelle des processus A et B est $global->user_list = array(1,2,3).
Le processus A modifie la variable $global->user_list en ajoutant un utilisateur 4.
Le processus B modifie la variable $global->user_list en ajoutant un utilisateur 5.
Le processus A réussit à définir la variable $global->user_list = array(1,2,3,4).
Le processus B réussit à définir la variable $global->user_list = array(1,2,3,5).
À ce stade, la variable définie par le processus B écrase celle définie par le processus A, entraînant une perte de données.

Ce problème est dû au fait que la lecture et la définition ne sont pas une opération atomique, ce qui entraîne des problèmes de concurrence.
Pour résoudre ces problèmes de concurrence, on peut utiliser l'interface de remplacement atomique cas.
Avant de modifier une valeur, l'interface cas vérifie si la valeur a été modifiée par d'autres processus en fonction de $old_value.
S'il y a eu des modifications, aucune substitution n'a lieu, et cela retourne false. Sinon, cela remplace et retourne true.
Voir l'exemple ci-dessous.

Attention :
Certaines données partagées peuvent être écrasées par concurrence sans problème, comme le plus haut enchère actuelle d'un objet dans un système d'enchères, ou le stock actuel d'un produit, etc.

Exemple

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

// Initialiser la liste
$global->user_list = array(1,2,3);

// Ajouter un valeur de manière atomique à 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);