PHP利用Mysql锁解决高并发
前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用Mysql的锁来解决高并发的问题
先看没有利用事务的时候并发的后果
创建库存管理表
CREATE TABLE `storage` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`number` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
创建订单管理表
CREATE TABLE `order` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`number` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=latin1
测试代码
$pdo = new PDO('mysql:host=127.0.0.1;port=3306; dbname=test','root','123456');
$sql="select `number` from storage where id=1 limit 1";
$res = $pdo->query($sql)->fetch();
$number = $res['number'];if($number>0)
{$sql ="insert into `order` VALUES (null,$number)";$order_id = $pdo->query($sql);if($order_id){$sql="update storage set `number`=`number`-1 WHERE id=1";$pdo->query($sql);}
}
我们预置库存是十个,然后执行ab测试查看结果
mysql> select * from storage-> ;
+----+--------+
| id | number |
+----+--------+
| 1 | -2 |
+----+--------+
1 row in set (0.00 sec)mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 22 | 10 |
| 23 | 10 |
| 24 | 8 |
| 25 | 8 |
| 26 | 7 |
| 27 | 6 |
| 28 | 4 |
| 29 | 3 |
| 30 | 2 |
| 31 | 2 |
| 32 | 2 |
| 33 | 1 |
+----+--------+
12 rows in set (0.00 sec)
得到了订单共有12
个,而库存表的库存也减到了-2
,这显然不符合实际逻辑的;
下面我们来看利用数据库行锁来解决这个问题
修改代码如下
$pdo = new PDO('mysql:host=127.0.0.1;port=3306; dbname=test','root','123456');
$pdo->beginTransaction();//开启事务
$sql="select `number` from storage where id=1 for UPDATE ";//利用for update 开启行锁
$res = $pdo->query($sql)->fetch();
$number = $res['number'];if($number>0)
{$sql ="insert into `order` VALUES (null,$number)";$order_id = $pdo->query($sql);if($order_id){$sql="update storage set `number`=`number`-1 WHERE id=1";if($pdo->query($sql)){$pdo->commit();//提交事务}else{$pdo->rollBack();//回滚}}else{$pdo->rollBack();//回滚}
}
查看结果
mysql> select * from storage;
+----+--------+
| id | number |
+----+--------+
| 1 | 0 |
+----+------
--+
1 row in set (0.00 sec)mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 1 | 10 |
| 2 | 9 |
| 3 | 8 |
| 4 | 7 |
| 5 | 6 |
| 6 | 5 |
| 7 | 4 |
| 8 | 3 |
| 9 | 2 |
| 10 | 1 |
+----+--------+
10 rows in set (0.00 sec)
很明显在利用了mysql锁之后,对库存进行了有效的控制,很好的解决了第一段代码里面,因为并发引起的一些逻辑性的问题
原文地址:https://segmentfault.com/a/1190000016251947
转载于:https://www.cnblogs.com/lalalagq/p/9971630.html
PHP利用Mysql锁解决高并发相关推荐
- 利用Redis锁解决高并发问题
利用Redis锁解决高并发问题 参考文章: (1)利用Redis锁解决高并发问题 (2)https://www.cnblogs.com/yszr/p/11698696.html 备忘一下.
- Redis锁解决高并发问题
Redis锁解决高并发问题 redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动. redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们 ...
- mysql乐观锁 秒杀_使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法...
数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...
- mysql 高并发写入锁表_使用mysql中的锁解决高并发问题
阿里云产品通用代金券,最高可领1888分享一波阿里云红包. 阿里云的购买入口 为什么要加锁 多核计算机的出现,计算机实现真正并行计算,可以在同一时刻,执行多个任务.在多线程编程中,因为线程执行顺序不可 ...
- 数据库并发抢红包_Redis悲观锁解决高并发抢红包的问题
悲观锁是一种利用数据库内部机制提供的锁的方法,也就是对更新的数据加锁,这样在并发期间一旦有一个事务持有了数据库记录的锁,其他的线程将不能再对数据进行更新了,这就是悲观锁的实现方式. 首先在 RedPa ...
- Zookeeper锁实现分布式锁解决高并发高可用秒杀系统
抢购前数据 库存表 订单表 zookeeper配置类 /*** @Author yqq* @Date 2022/05/30 23:24* @Version 1.0*/ @Configuration p ...
- Spring Boot实战解决高并发数据入库: Redis 缓存+MySQL 批量入库
前言 最近在做阅读类的业务,需要记录用户的PV,UV: 项目状况:前期尝试业务阶段: 特点: 快速实现(不需要做太重,满足初期推广运营即可) 快速投入市场去运营 收集用户的原始数据,三要素: 谁 在什 ...
- 乐观锁 -业务判断 解决高并发问题
在解决高并发问题时,如果是分布式系统显然我们只能够使用数据库端加锁机制来解决这个问题,但是这种同步机制或者数据库物理锁机制会牺牲一部分的性能,所以常常以另外一种方式来解决这个问题 就是乐观锁模式 银行 ...
- java 高并发商城库存订单处理,下单减库存,如何解决高并发减库存问题
下单减库存,如何解决高并发减库存问题 1. 减库存 一般下单减库存的流程大概是这样的: 1.查询商品库存.这里直接查的Redis中的库存. 2.Redis中的库存减1.这里用到的Redis命令是:in ...
最新文章
- DC/DC电源模块介绍
- python一千行入门代码-Python – 一次从文件中读取1000行
- 2019年四月计算机语言排名,2019编程语言排行榜_编程语言排行榜2019年4月 TIOBE编程语言排行榜2019年最...
- 06 | 全局锁和表锁 : 给表加个字段怎么有这么多阻碍
- 再深入 HTTP Referer【转】
- Printer Processor 导致的一个问题
- Facebook广告投放有什么策略?
- 如何卸载FileZilla的Ftp服务
- HTML转义字符表的使用
- 下软件,就靠这几个网站
- 在ideaIU上使用JDBC连接MySQL及简单操作
- 最全 Yaml 语法详解
- 微信小程序点播音频服务器,微信小程序无法播放本地音频
- 机器学习入门之线性回归(1)- 单特征(python实现)
- Java Cryptography
- Massive MIMO简介
- Nlite后期处理技术小结(第三次更新...全文完)(by bluewind)
- 【MATLAB】基本绘图 ( Marker 设置 | 设置 Marker 边框 | 设置 Marker 填充 )
- ESP32创建局域网服务器VScode
- googleapis.com替换CDN
热门文章
- Centos镜像使用帮助
- e_msg_c_gs_enter_gs_req
- ubuntu 14.04 登录 界面 root
- POST方式提交乱码解决
- 站内搜索--3--之Lucene.Net使用
- MedMNIST:18个数据集开启2D+3D医学影像之旅,可免费下载
- 年薪28万 ~60万+,北理工计算机学院可视媒体计算团队诚招博士后
- 坐标北京,Paddle Lite​ 线下交流会,助力算法落地​
- CVPR 2019 | 步步为营!通过迭代式模糊核预测提高超分辨质量
- CVPR 2019 CLIC 图像压缩挑战赛冠军方案解读