MySQL 加锁处理分析 ---非常牛逼
http://hedengcheng.com/?p=771
mysql lock in share mode 和 select for update
工作需要,接触到以下两个mysql sql语法:
select lock in share mode
select for update
- 1
- 2
从官网上查找到对应的章节,属于Locking Reads里面的内容,具体链接如下:
根据官网介绍,这两个语句是在事务内起作用的,所涉及的概念是行锁。它们能够保证当前session事务所锁定的行不会被其他session所修改(这里的修改指更新或者删除)。两个语句不同的是,一个是加了共享锁而另外一个是加了排它锁。可以这么理解,共享锁允许其他事务加共享锁读取,但是,不允许其他事务去做修改,或者加排它锁。而排它锁显得更加严格,不允许其他事务加共享锁或者排它锁,更加不允许其他事务修改加锁的行。
说到这里,行锁有什么用呢?设想下面这种场景:
1) 读取一行数据
2) 根据读取到的数据去更新其他数据
假设在1)和2)之间,有个其他的user session刚好修改了你读取的那行数据,那么你下面的更新就有可能会出错!因为关联的数据产生了变化!
行锁就能够保证不会出现上面所说的这种尴尬的场景。
实践了一把,下面记录它们的用处:
测试用的表结构并插入一行记录:
use test;
create table tb_test (
id int primary key,
col1 varchar(20)
) engine = innodb default character set = 'utf8';
insert into tb_test(id, col1) values(1, 'AAA');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
1. select lock in share mode
1.1 使用示例
session 1:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
- 1
- 2
open session 2:
update tb_test set col1 = 'BBB' where id = 1;
- 1
这个时候可以观察到session2处于blocking状态….
直到
session 1:
commit;
- 1
这个时候session2更新成功了。
这里也就验证了lock in share mode可以在事务中保证锁定的行不被其他session所更改。
1.2 注意死锁
使用lock in share mode具有很高的风险,看下面的案例:
session 1:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
- 1
- 2
open session2:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
- 1
- 2
这个时候两个session同时持有id = 1这行数据的共享锁。这个时候我们在session 1里面执行update操作:
session 1:
update tb_test set col1 = 'AAA' where id = 1;
- 1
卡住了!!!! ????
这个时候session1必须等待session2退出事务或者等待直到锁超时:
锁超时的情况:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
如果我们在session 2里面执行:
session2:
update tb_test set col1 = 'BBB' where id = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
- 1
- 2
- 3
这个时候mysql检测到会发生死锁,会中断当前事务该语句的执行,重新开启一个新的事务(应该就是相当于session2先退出事务,然后再开启一个事务吧)。
这个时候session1可以更新成功了。
上面的例子可以看出使用lock in share mode比较危险,很可能因为其他session同时加了这种锁,导致当前session无法进行更新,进而阻塞住。
2. select for update
select for update加的是排它锁,所以没有上面lock in share mode所产生的死锁,因为一个session加了这种锁,其他session除了读取操作,其他操作都不能进行,如更改操作,或者加锁,共享锁和排它锁都不可以。
2.1 使用示例
下面演示一下用法:
session 1:
set autocommit = 0;
select * from tb_test where id = 1 for update;
- 1
- 2
open session 2:
update tb_test set col1 = 'BBB' where id = 1;
- 1
这个时候session 2处于blocking状态
我们手动kill掉session 2, 按Ctrl + C。
然后执行:
session 2:
set autocommit = 0;
select * from tb_test where id = 1 for update;
- 1
- 2
还是blocking状态,证明其他session的事务不能对已经加了排它锁(for update)的行再加排它锁。
kill掉,再来
session 2:
set autocommit = 0;
select * from tb_test where id = 1 lock in share mode;
- 1
- 2
还是blocking状态,证明其他session的事务不能对已经加了排它锁(for update)的行再加共享锁(lock in share mode)。
当然,如果使用select for update的时候,如果锁定当前行的事务一直不退出,将会导致其他进行这个行更改操作的session一直阻塞。(没有试是否有超时的情况)
2. 总结
因此,无论在使用select lock in share mode 或者 select for update,都应该尽快释放锁。
确实是这样的,LOCK IN SHARE MODE是读锁(只是不让别人写),FOR UPDATE是写锁(还不让别人加读锁),读锁升级成写锁是可能产生死锁的(但写锁降级成读锁则不会,我还真不知道MySQL如何对锁降级),所以程序中需要考虑超时的问题(或者重试或者放弃)。
所以大部分情况下都如果SELECT后接下来会有UPDATE动作的话,一般会用FOR UPDATE而不是LOCK IN SHARE MODE。
MySQL 加锁处理分析 ---非常牛逼的更多相关文章
- MySQL 加锁处理分析 转
MySQL 加锁处理分析 转 http://hedengcheng.com/?p=771 十二 13th, 2013 发表评论 | Trackback 1 背景 1 1.1 M ...
- 转载-MySQL 加锁处理分析
MySQL 加锁处理分析 发表于 2013 年 12 月 13 日 由 hedengcheng 1 背景 1 1.1 MVCC:Snapshot Read vs Current Re ...
- (转)MySQL 加锁处理分析
MySQL 加锁处理分析 原文:http://hedengcheng.com/?p=771 1 背景 1 1.1 MVCC:Snapshot Read vs Current Read ...
- MySQL 加锁处理分析
1 背景 1 1.1 MVCC:Snapshot Read vs Current Read 2 1.2 Cluster Index:聚簇索引 3 1.3 2P ...
- MySQL 加锁处理分析-转载
来自何登成的技术博客 1.1 MVCC:Snapshot Read vs Current Read 2 1.2 Cluster Index:聚簇索引 3 1.3 ...
- MySQL 加锁处理分析<转>
1 背景 1 1.1 MVCC:Snapshot Read vs Current Read 2 1.2 Cluster Index:聚簇索引 3 1.3 2P ...
- MySQL加锁处理分析(转)
add by zhj: 非常棒的一篇文章,是我见过的讲加锁最棒最详细的文章了.之前听过网易的<MySQL微专业>,里面的课程讲的也很好,但锁这块讲的跟 这篇文章相比,还是有差距的.网易&l ...
- [好文分享]MySQL 加锁处理分析
原文转自:http://hedengcheng.com/?p=771 背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经 ...
- 转:mysql加锁处理分析
MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备就My ...
随机推荐
- Memcache的安装与配置
因为单位要求修复Memcached的DDOS漏洞,整理了本文.之前的文章防止Memcached的DDOS攻击另外一个思路 提到了解决方案,我们使用的版本较低,因此需要对 Memcached 进行升级, ...
- C#程序集Assembly学习随笔(第一版)_AX
①什么是程序集?可以把程序集简单理解为你的.NET项目在编译后生成的*.exe或*.dll文件.嗯,这个确实简单了些,但我是这么理解的.详细:http://blog.csdn.net/sws8327/ ...
- Tar打包、压缩与解压缩
tar在linux上是常用的打包.压缩.加压缩工具,他的参数很多,折里仅仅列举常用的压缩与解压缩参数 参数: -c :create 建立压缩档案的参数: -x : 解压缩压缩档案的参数: -z : 是 ...
- 反向解析与PTR(Pointer Record)
PTR记录,是电子邮件系统中的邮件交换记录的一种:另一种邮件交换记录是A记录(在IPv4协议中)或AAAA记录(在IPv6协议中).PTR记录常被用于反向地址解析. PTR记录 Pointer ...
- 使用pm2管理node.js应用
中文文档:https://pm2.io/doc/zh/runtime/quick-start/ pm2是从nodejs衍生出来的服务器进程管理工具,可以做到开机就启动nodejs.当然了,有些运维同学 ...
- org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.xugao.bean.MemberLevel.memberpointrate
由于数据不合法的原因,好几次遇到: org.hibernate.PropertyAccessException: Null value was assigned to a property of pr ...
- swift3.0:NSURLSession的使用
一.说明 NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍. 二.介绍: URLSession 类支 ...
- Entity Framework 与 LINQ to SQL
Entity Framework和LINQ to SQL到底有什么区别?这是一个很常见的问题.下面的表中简要罗列了两种技术的主要区别. LINQ to SQL Entity Framework 复杂度 ...
- 【大数据】大数据处理-Lambda架构-Kappa架构
大数据处理-Lambda架构-Kappa架构 elasticsearch-head Elasticsearch-sql client NLPchina/elasticsearch-sql: Use S ...
- SSAS知识回放之订单数据分析
1:目标 基于已经做好的DW,利用SSAS实现一个多维数据模型的创建,通过浏览可以简单的实现订单数据的分析 2:步骤 2.1:添加数据源 如下图所示,创建一个数据仓库层的数据源连接 2.2:添加数据源 ...