千家信息网

php多进程模拟并发事务产生的问题说明

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容介绍了"php多进程模拟并发事务产生的问题说明"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
千家信息网最后更新 2026年11月03日php多进程模拟并发事务产生的问题说明

本篇内容介绍了"php多进程模拟并发事务产生的问题说明"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

本文通过实例代码给大家介绍了关于php多进程模拟并发事务产生的一些问题,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

表

drop table if exists `test`;create table if not exists `test` ( id int not null auto_increment ,  count int default 0 ,  primary key `id` (`id`)) engine=innodb character set utf8mb4 collate = utf8mb4_bin comment '测试表';insert into test (`count`) values (100);

php 代码

// 进程数量$pro_count = 100;$pids = [];for ($i = 0; $i < $pro_count; ++$i){ $pid = pcntl_fork(); if ($pid < 0) {  // 主进程  throw new Exception('创建子进程失败: ' . $i); } else if ($pid > 0) {  // 主进程  $pids[] = $pid; } else {  // 子进程  try {   $pdo = new PDO(...);   $pdo->beginTransaction();   $stmt = $pdo->query('select `count` from test');   $count = $stmt->fetch(PDO::FETCH_ASSOC)['count'];   $count = intval($count);   if ($count > 0) {    $count--;    $pdo->query('update test set `count` = ' . $count . ' where id = 2');   }   $pdo->commit();  } catch(Exception $e) {   $pdo->rollBack();    throw $e;  }  // 退出子进程  exit; }}

期望的结果

期望 count 字段减少的量超过 100,变成负数!也就是多减!

实际结果

并发 200 的情况下,运行多次后的结果分别如下:

1. count = 65
2. count = 75
3. count = 55
4. count = 84
...

与期望结果相差甚远!为什么会出现这样的现象呢?

解释

首先清楚下目前的程序运行环境,并发场景。何为并发,几乎同时执行,称之为并发。具体解释如下:

进程 过程 获取 更新
1-40 同时创建并运行 100 99
41-80 同时创建并运行 99 98
81 - 100 同时创建并运行 98 97

对上述第一行做解释,第 1-40 个子进程的创建几乎同时,运行也几乎同时:

进程 1 获取 count = 100,更新 99
进程 2 获取 count = 100,更新 99
...
进程 40 获取 count = 100,更新 99

所以,实际上这些进程都做了一致的操作,并没有按照预期的那样:进程1 获取 count=100,更新 99;进程 2 获取进程1更新后的结果 count=99,更新98;...;进程 99 获取进程 98更新后的结果count=1,更新0
,产生的现象就是少减了!!

结论

采用上述做法实现的程序,库存总是 >= 0。

疑问

那要模拟超库存的场景该如何设计程序呢?

仍然采用上述代码,将以下代码:

if ($count > 0) { $count--; $pdo->query('update test set `count` = ' . $count . ' where id = 2');}

修改成下面这样:

if ($count > 0) { $pdo->query('update test set `count` = `count` - 1 where id = 2');}

结果就会出现超库存!!

库存 100,并发 200,最终库存减少为 -63。为什么会出现这样的情况呢?以下描述了程序运行的具体过程

进程 1 获取库存 100,更新 99
进程 2 获取库存 100,更新 98(99 - 1)
进程 3 获取库存 100,更新 97(98 - 1)
....
进程 168 获取库存 1 ,更新 0(1-1)
进程 169 获取库存 1 ,更新 -1(0 - 1)
进程 170 获取库存 1 ,更新 -2(-1 - 1)
....
进程 200 获取库存 1,更新 -63(-62 - 1)

现在看来很懵逼,实际就是下面这条语句导致的:

$pdo->query('update test set `count` = `count` - 1 where id = 2');

这边详细阐述 进程 1,简称 a;进程 2,简称 b 他们具体的执行顺序:

1. a 查询到库存 100
2. b 查询到库存 100
3. a 更新库存为 99(100 - 1),这个应该秒懂
4. b 更新库存为 98(99 - 1)
- b 在执行更新操作的时候拿到的是 a 更新后的库存!
- 为什么会这样?因为更新语句是 `update test set count = count - 1 where id = 2`

"php多进程模拟并发事务产生的问题说明"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

进程 更新 库存 结果 运行 同时 代码 实际 程序 事务 问题 情况 过程 期望 解释 内容 场景 就是 更多 现象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 有格互联网科技 湖北九亚互联网络科技有限公司 高科技互联网 中资互联网科技 世界互联网领先科技成果 迪茉互联网科技 互联网科技logo设计 一五八零互联网科技 恒生科技互联网指数分析 剑昆互联网络科技有限公司临桂 汽车互联网创新科技园 贵州叶脉互联网科技有限公司所属行业 阿大互联网科技有限公司 坤平互联网科技 互联网科技研发水平 浙南科技城互联网大厦建设工程 西安小鹰速贷互联网科技有限公司 上海钢联属于互联网科技股吗 互联网企业科技类企业如何做账 平安好医生打造互联网科技医疗 互联网金融监管科技数据 互联网科技公司电话 上海喔噻互联网科技 友谊互联网络科技 汉立互联网科技有限公司联系电话 广州优美互联网科技 广州慧亚互联网科技怎么样 互联网金融科技公司干啥的 湖北码尼互联网科技有限公司电话 苏州铭阳互联网科技有限公司
0