cas

(Richiede Workerman versione>=3.3.0)

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

Sostituzione atomica, sostituisci $old_value con $new_value.
Solo quando il valore corrispondente a questa chiave non è stato modificato da altri client dopo l'ultima lettura da parte del client corrente, è possibile scrivere il valore.

Parametri

$key

Chiave. (Ad esempio $global->abc, abc è la chiave)

$old_value

Dati vecchi

$new_value

Dati nuovi

Valore restituito

Restituisce true se la sostituzione ha avuto successo, altrimenti restituisce false.

Spiegazione:

Quando più processi operano contemporaneamente sulla stessa variabile condivisa, a volte è necessario considerare il problema della concorrenza.

Ad esempio, due processi A e B aggiungono contemporaneamente un membro all'elenco degli utenti.
Attualmente l'elenco degli utenti per i processi A e B è $global->user_list = array(1,2,3).
Il processo A opera sulla variabile $global->user_list, aggiungendo un utente 4.
Il processo B opera sulla 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.
In questo momento, la variabile impostata dal processo B sovrascrive la variabile impostata dal processo A, causando la perdita dei dati.

Ciò è dovuto al fatto che la lettura e la scrittura non sono un'operazione atomica, causando problemi di concorrenza.
Per risolvere questo problema di concorrenza, è possibile utilizzare l'interfaccia di sostituzione atomica cas.
Prima di modificare un valore, l'interfaccia cas verifica se questo valore è stato modificato da altri processi in base a $old_value.
Se è stato modificato, non viene sostituito e restituisce false. Altrimenti restituisce true.
Vedere l'esempio seguente.

Nota:
Alcuni dati condivisi sovrascritti da concorrenza non sono un problema, ad esempio il sistema di asta attuale offerta massima o l'attuale inventario di un certo prodotto.

Esempio

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

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

// Aggiungi in modo atomico 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);