php - 如何检查条件是否为真,然后在竞争条件下插入一些东西
问题描述
我们有一个 api 函数,它使用选择查询检查数据库的条件,然后如果它是真的,我们只想一次向数据库插入一些东西,例如插入到数据库中插入完成。问题是当我们多次调用此 api 函数时同时发生竞争条件,换句话说,假设我们调用此函数 2 次,第一次请求检查条件是否为真,然后第二次请求检查该条件是否为真,因此它们确实插入数据库。但是我们希望在检查条件时没有其他人可以再次检查它,直到我们进行插入。
我们使用 php/Laravel 并且知道一些方法,比如使用insert into ... select
或使用类似的东西replace into ...
等等。
$order = Order::find($orderId);
$logRefer = $order->user->logrefer;
if (!is_null($logRefer) && is_null($logRefer->user_turnover_id)) {
$userTurnover = new UserTurnover();
$userTurnover->user_id = $logRefer->referrer_id;
$userTurnover->order_id = $order->id;
$userTurnover->save();
$logRefer->order_id = $order->id;
$logRefer->user_turnover_id = $userTurnover->id;
$logRefer->save();
}
如果logrefer
没有找到,只设置一次并对应user-turnover
一次。我们希望只看到user-turnover
与此订单相关的一个,但在同时运行多次后,我们看到多个user-turnover
已插入。
解决方案
当操作需要按顺序进行时,我通常会利用事务,但我认为在您的情况下,情况有点复杂,因为如果函数正在运行,还需要有条件地评估条件。所以我可以给你的想法是在数据库上有一个变量(另一个表)用作信号量,它允许或不允许对表执行操作(条件是您设置或取消设置信号量的值) . 我认为作为优秀的程序员,信号量在很多并发函数的情况下都很有用。
推荐阅读
- vue-multiselect - 如何为 vuejs 多选 optionGroup 中的 group-label 和 group-values 自定义 css?
- python - 尝试安装 MySQL 客户端时,出现此错误
- python - 通过定义引用另一个类的银行帐户的升级函数进行升级(python)
- azure - 如何从 Azure DevOps 发布管道将 docker 容器部署到 Ubuntu 服务器实例?
- python - python dict到json转换pandas
- apache-flink - 尽管重试,flink如何保证kafka记录只发生一次
- javascript - 无法正确执行 else if 语句
- django - Django 管理员。如何更改字段标签的位置
- javascript - 为什么,当滚动页面时,当滚动到带有水平块的块时,它并不总是滚动?
- json - 如何将输出转换为 JSON 格式?