MySQL 使用 SELECT … FOR UPDATE 做事务写入前的确认

以MySQL 的InnoDB 为例,预设的 Tansaction isolation level 为 REPEATABLE READ,在 SELECT 的读取锁定主要分为两种方式:SELECT … LOCK IN SHARE MODE

SELECT … FOR UPDATE

这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁 。

简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用 SELECT … UPDATE。

举个例子:假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,然后才把数量更新为1。

不安全的做法:1 SELECT quantity FROM products WHERE id=3;

1 UPDATE products SET quantity = 1 WHERE id=3;

为什么不安全呢?

少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。

如果我们需要在 quantity>0 的情况下才能扣库存,假设程序在第一行 SELECT 读到的 quantity 是 2 ,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成 0 了,但是程序却浑然不知,将错就错的 UPDATE 下去了。

因此必须透过的事务机制来确保读取及提交的数据都是正确的。

于是我们在MySQL 就可以这样测试:(注1)1 SET AUTOCOMMIT=0;

2 BEGIN WORK;

3 SELECT quantity FROM products WHERE id=3 FOR UPDATE;

此时 products 数据中 id=3 的数据被锁住(注3),其它事务必须等待此次事务提交后才能执行 SELECT * FROM products WHERE id=3 FOR UPDATE (注2)如此可以确保 quantity 在别的事务读到的数字是正确的。1 UPDATE products SET quantity = '1' WHERE id=3 ;

2 COMMIT WORK;

提交(Commit)写入数据库,products 解锁。

注1:BEGIN/COMMIT 为事务的起始及结束点,可使用二个以上的MySQL Command 视窗来交互观察锁定的状况。

注2:在事务进行当中,只有SELECT … FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT … 则不受此影响。

注3:由于InnoDB 预设为Row-level Lock,数据列的锁定可参考这篇。

注4:InnoDB 表单尽量不要使用LOCK TABLES 指令,若情非得已要使用,请先看官方对于InnoDB 使用LOCK TABLES 的说明,以免造成系统经常发生死锁。

以上就是Mysql高并发加锁事务处理的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

mysql 高并发加锁_Mysql高并发加锁事务处理相关推荐

  1. mysql lvs 读写分离_mysql高可用架构方案之二(keepalived+lvs+读写分离+负载均衡)

    mysql主从复制与lvs+keepalived实现负载高可用 目录 1.前言    4 2.原理    4 2.1.概要介绍    4 2.2.工作原理    4 2.3.实际作用    4 3方案 ...

  2. mysql 的高并发访问_mysql高并发解决方案

    mysql高并发的解决方法有: 优化SQL语句,优化数据库字段,加缓存,分区表,读写分离以及垂直拆分,解耦模块,水平切分等. 高并发大多的瓶颈在后台,在存储mysql的正常的优化方案如下: (1)代码 ...

  3. MySQL单机并发量_mysql百万并发量-MySQL集群能支持100万个并发请求吗

    当然支持100万并发. 首先,我们必须做出决定,把阅读和写作分开. 然后,它取决于你需要分配多少个单元用于写作和阅读. 我的SQL集群不建议您使用它,因为有太多的错误. 所有这些都需要先进行压力测试. ...

  4. mysql 主备及时_MySQL高可用(二)主备延时如何解决?

    从上篇文章我们知道主备同步是依赖于 binlog,主库负责生产 binlog,备库负责消费 binlog,从而实现主备同步. 今天我们来学习一下主备同步里的一个重点的问题:主备延时. 主备延时,简单来 ...

  5. mysql innodb 多线程插入_mysql innodb 并发插入问题,包大量死锁错误

    开了10个并发写线程,没1000条记录批量提交一次,结果mysql包大量死锁错误! "Deadlock found when trying to get lock; try restarti ...

  6. mysql故障排查思路_Mysql高负载排查思路

    发现问题 top命令 查看服务器负载,发现 mysql竟然百分之两百的cpu,引起Mysql 负载这么高的原因,估计是索引问题和某些变态SQL语句. 排查思路 1. 确定高负载的类型,top命令看负载 ...

  7. mysql应用层透明扩展_MySQL高扩展和高可用

    # MySQL高扩展和高可用 * [真题](https://www.kancloud.cn/ranjun940726/php_interview/596349#_2) * [分区表的原理](https ...

  8. mysql mha好吗_MySQL高可用方案MHA的一些总结和思考

    原标题:MySQL高可用方案MHA的一些总结和思考 MySQL高可用方案中MHA绝地是一个相当成熟的实现.对于数据的切换,其实MGR也能很好的完成,也就是说,数据层面的角色切换已经刻意很平滑的做好了, ...

  9. mysql高可用方案_MySQL高可用集群方案

    一.Mysql高可用解决方案 方案一:共享存储 一般共享存储采用比较多的是 SAN/NAS 方案. 方案二:操作系统实时数据块复制 这个方案的典型场景是 DRBD,DRBD架构(MySQL+DRBD+ ...

最新文章

  1. 2022年六大值得关注的边缘计算趋势
  2. Spoken English(021)
  3. 伪命题:我们来谈谈校招生起薪的问题,它对你来说重要吗?
  4. RuoYiConfig中加入自定义属性值获取不到解决办法?
  5. 数据结构知识点总结pdf_闭关修炼31天,“啃完”346页pdf,我终于四面拿下阿里offer!...
  6. Unity官方案例精讲_2015_优化
  7. python通过http上传文件
  8. 【操作系统实验】设备驱动(Linux环境下)
  9. android应用程序后台运行权限,检查Android应用程序是否在后台运行
  10. Python基础教学3:变量名和赋值
  11. 用计算机打字用英语怎么说,打字用英语怎么说
  12. 在linux基础上开发内核,科学院在Linux内核基础上,开发出中文操作系统是()。A.中科LinuxB.熊猫LinuxC.红旗Linux...
  13. Apollo星火计划学习笔记第四讲2——高精地图定位模块
  14. matlab可以仿真特殊电机,基于Matlab的异步电动机矢量控制系统的仿真研究
  15. 磁盘被格式化了的文件恢复办法
  16. 英尺 厘米_我们如何在80小时内建立33,000英尺高的社区?
  17. PyQt MCV模型绑定到配置实战
  18. 自制第三方库lzlzhn的介绍及使用-更新简化模块名称
  19. 应用XGboost实现多分类模型实践
  20. 汉王引领双核手写识别新纪元 开启3G人脸开机时代

热门文章

  1. x-manager 管理 kvm虚拟机
  2. django使用templates模板
  3. jquery实现后台系统左侧菜单的点击展开/收缩二级菜单效果
  4. Redis持久化实践及数据恢复
  5. 学习javascript 的一点感想
  6. Aspose.Cells小实例
  7. 把一个表中的数据插入到另一个表
  8. Python 常用文件
  9. hdu 2085 核反应堆
  10. PostgreSQL的 initdb 源代码分析之九