返回介绍

1.15.1.2.2 cas

发布于 2020-05-17 11:52:42 字数 4365 浏览 767 评论 0 收藏 0

(要求Workerman版本>=3.3.0)

bool GlobalDataClient::cas(string $key, mixed $old_value, mixed $new_value)

原子替换,用$new_value替换$old_value。 仅在当前客户端最后一次取值后,该key对应的值没有被其他客户端修改的情况下, 才能够将值写入。

参数

$key

键值。(例如$global->abcabc就是键值)

$old_value

老数据

$new_value

新数据

返回值

替换成功返回true,否则返回false。

说明:

多进程同时操作同一个共享变量时,有时候要考虑并发问题。

例如A B两个进程同时给用户列表添加一个成员。
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。
见下面示例。

注意: 有些共享数据被并发覆盖是没问题的,例如竞拍系统某拍卖物当前最大报价,例如某商品当前库存等。

范例

require_once __DIR__ . '/../src/Client.php';

$global = new GlobalDataClient('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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文