cas

(richiesta Workerman versione >=3.3.0)

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

Sostituzione atomica, sostituisce $old_value con $new_value.
Può scrivere il valore solo se, dopo l'ultimo recupero da parte del client corrente, il valore corrispondente a quella chiave non è stato modificato da altri client.

Parametri

$key

Chiave. (ad esempio $global->abc; abc è la chiave)

$old_value

Valore precedente

$new_value

Nuovo valore

Valore di ritorno

Restituisce true se la sostituzione è avvenuta con successo, altrimenti restituisce false.

Descrizione:

Quando più processi operano simultaneamente sulla stessa variabile condivisa, a volte è necessario considerare i problemi di concorrenza.

Ad esempio, i processi A e B aggiungono contemporaneamente un membro alla lista utenti.
Al momento, la lista utenti di entrambi i processi A e B è $global->user_list = array(1,2,3).
Il processo A modifica la variabile $global->user_list, aggiungendo un utente 4.
Il processo B modifica la variabile $global->user_list, aggiungendo un utente 5.
Il processo A imposta la variabile $global->user_list = array(1,2,3,4) con successo.
Il processo B imposta la variabile $global->user_list = array(1,2,3,5) con successo.
A questo punto, la variabile impostata dal processo B sovrascriverà quella impostata dal processo A, portando a una perdita di dati.

Quello sopra accade perché la lettura e l'impostazione non sono un'operazione atomica, causando problemi di concorrenza.
Per risolvere questo problema di concorrenza, è possibile utilizzare l'interfaccia di sostituzione atomica cas.
L'interfaccia cas prima di cambiare un valore,
verifica se il valore è stato cambiato da altri processi in base a $old_value,
se c'è stata una modifica, non sostituisce e restituisce false. Altrimenti restituisce true dopo la sostituzione.
Vedi l'esempio qui sotto.

Attenzione:
Ci sono alcuni dati condivisi che possono essere sovrascritti in modo concorrente senza problemi, ad esempio, il massimo rilancio attuale di un'asta in un sistema di offerte, ad esempio, l'attuale disponibilità di un prodotto, ecc.

Esempio

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

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

// Aggiungi atomicamente un valore a 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);