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。
不安全的做法:
为什么不安全呢?
少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。
如
果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2
,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE
下去了。
因此必须透过的事务机制来确保读取及提交的数据都是正确的。
于是我们在MySQL 就可以这样测试:
此时products 数据中id=3 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行
SELECT * FROM products WHERE id=3 FOR UPDATE 如此可以确保quantity 在别的事务读到的数字是正确的。
提交(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 SELECT ... FOR UPDATE 的Row Lock 与Table Lock
上面介绍过SELECT ...
FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level
Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table
Lock (将整个数据表单给锁住)。
举个例子:
假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。
例1: (明确指定主键,并且有此数据,row lock)
例2: (明确指定主键,若查无此数据,无lock)
例2: (无主键,table lock)
例3: (主键不明确,table lock)
例4: (主键不明确,table lock)
注1: FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。
注2: 要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试。
例
MySQL update && select
CREATE TABLE `testupdate` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`val` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
update testupdate
set val = val+1
where id = 1 and @value := val+1;
select @value;
原文:http://www.jb51.net/article/42778.htm
mysql SELECT FOR UPDATE语句使用示例的更多相关文章
- 数据库中Select For update语句的解析
----------- Oracle -----------------– Oracle 的for update行锁 键字: oracle 的for update行锁 SELECT-FOR UPDAT ...
- Select For update语句浅析 (转)
Select … for update语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句 ...
- mysql: SELECT ... FOR UPDATE 对SELECT语句的阻塞实验
开两个连接A, B, 分别执行以下三个sql start 和 start ; 在A执行完1和2后, B执行1, 正常B执行2, 立即返回B执行3, 这时候被阻塞了 A执行3后, B的3立即返回 可以得 ...
- 在MySQL中阻止UPDATE语句没有添加WHERE条件的发生
如果在生产环境中使用UPDATE语句更新表数据,此时如果忘记携带本应该添加的WHERE条件,那么..Oh,no…后果可能不堪设想.那么有没有什么办法可以阻止这样的事情发生,又不使用任何的审核工具呢.. ...
- MYSQL SELECT FOR UPDATE
问题说明: 最近遇到一个问题,多个WORKER同时向MYSQL数据库请求任务,如何实现互斥?例如: SELECT * FROM student WHERE id > 10 LIMIT 100; ...
- 转 MYSQL SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads
原文: http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html In some circumstances, a consis ...
- sql server中同时执行select和update语句死锁问题
原始出处 http://oecpby.blog.51cto.com/2203338/457054 最近在项目中使用SqlServer的时候发现在高并发情况下,频繁更新和频繁查询引发死锁.通常我们知道如 ...
- Select For update语句浅析
Select -forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不 ...
- sql server中高并发情况下 同时执行select和update语句死锁问题 (二)
SQL Server死锁使我们经常遇到的问题,数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁.希望对您学习SQL Server死锁方面能有所帮助. 死锁对于DBA或是数据 ...
随机推荐
- Mac OS 下 eclipse中文乱码解决方法(eclipse for mac 中文乱码)
由于一些java源码是从其他人那里拷贝过来,放入Mac os 版本的eclipse下,发现中文都是乱码.经过小试,可以解决. 1.打开eclipse 偏好设置 2.General ——>Cont ...
- android开发之生命周期
android开发之生命周期 一:Activity的生命周期: 这几天了了解了安卓Activity的生命周期,对于生命周期有了大概的理解: 一个Activity的生命周期也就是Activity从生成到 ...
- 【BZOJ-1858】序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1961 Solved: 991[Submit][Status ...
- Jenkins 2.x版本修改启动端口号(Windows)
可能有一些原因,8080端口被占用了,无法使用时需要修改jenkins的启动端口号. 如果首次安装,建议先停止原有系统的8080端口占用,等jenkins安装完成后,再进行修改,然后该回8080的原系 ...
- POJ3468 A Simple Problem with Integers
Description 给出了一个序列,你需要处理如下两种询问. "C abc"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000). "Q ...
- 加州大学伯克利分校Stat2.2x Probability 概率初步学习笔记: Final
Stat2.2x Probability(概率)课程由加州大学伯克利分校(University of California, Berkeley)于2014年在edX平台讲授. PDF笔记下载(Acad ...
- 【JavaScript与JQuery获取H2的内容】
撰写日期:2016-7-13 11:05:07 JavaScript与JQuery获取DOM内容是有区别的,接下来看一例子 栗子: Jquery-获取H3中的内容然后Dom转换为Jquery < ...
- Android中的Binder机制的简要理解
转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...
- SPOJ:ABCDEF
传送门 废话不说,这道题暴力枚举是$O(N^6)$,显然无法承受. 推导一下 $(x_1*x_2+x_3)/x_4-x_5=x_6$ $x_1*x_2+x_3=x_4*(x_5+x_6)$ 等式左边和 ...
- uC/OS-II应用程序exe
ECHO OFFECHO *******************************************************************************ECHO * ...