工作需要,接触到以下两个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 加锁处理分析 ---非常牛逼相关推荐

  1. linux mysql 释放x锁_MySQL 加锁处理分析-转载

    背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...

  2. mysql udf提权_MySQL日志安全分析技巧

    常见的数据库攻击包括弱口令.SQL注入.提升权限.窃取备份等.对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源. 0x01 Mysql日志分析 general query log ...

  3. 阿里云 mysql日志分析_mysql 慢日志分析-阿里云开发者社区

    启用 slow log 有两种启用方式: 1, 在my.cnf 里 通过 log-slow-queries[=file_name] 2, 在mysqld进程启动时,指定--log-slow-queri ...

  4. mysql用户阻塞数_MySQL实例阻塞分析一例(线程statistics状态)

    本文用实例来分析MySQL阻塞-线程statistics状态. 一. 现象 某日下午下班后低峰期,现网MySQL一个库突然报出大量慢sql,状态是 statistics,但是过后拿这些sql去执行的时 ...

  5. mysql 执行效率命令_MySQL优化--explain 分析sql语句执行效率

    MySQL优化--explain 分析sql语句执行效率 explain 命令 explain 命令在解决数据库性能上市第一推荐使用命令,大部分的性能问题可以通过此命令来简单解决,explain可以用 ...

  6. mysql 慢日志可视化_Mysql 慢日志分析系统搭建 —— Box Anemometer

    背景: ​慢日志是分析定位问题的利器,但是在日常实际应用中,mysql自动生成的慢日志是杂乱无章的,不便于我们的使用. 这里介绍利用开源项目 Box Anemometer来搭建一个图形可视化的慢日志分 ...

  7. mysql启动失败分析_MySQL启动失败分析与解决

    1, 背景 早上过来发现电脑非正常关机了,进mysql发现报错: mysql -uroot -p Enter password: ERROR 2002 (HY000): Can"t conn ...

  8. mysql源码分析_MySQL · 源码分析 · 词法分析及其性能优化

    简介 MySQL 支持标准的 SQL 语言,具体实现的时候必然要涉及到词法分析和语法分析.早期的程序可能会优先考虑手工实现词法分析和语法分析,现在大多数场合下都会采用工具来简化实现.MySQL.Pos ...

  9. mysql insert执行过程_MySQL · 源码分析 · 一条insert语句的执行过程

    本文只分析了insert语句执行的主路径,和路径上部分关键函数,很多细节没有深入,留给读者继续分析 create table t1(id int); insert into t1 values(1) ...

最新文章

  1. up 手环服务器不稳定,Up手环停产:曾经风光无限的Jawbone快不行了
  2. 开源自制6通道航模遥控器,Arduino Pro Mini NRF24L01模块
  3. LiveVideoStackCon 倒数计时:0
  4. 各种组件的js 获取值 / js动态赋值
  5. java utf8 转换al32utf8_java与Unicode
  6. static和extern的用法总结
  7. Python中表达式和语句及for、while循环练习
  8. mysql双一参数_MySQL 的双1设置-数据安全的关键参数(案例分享)
  9. mysql将一个表的字段更新到另一个表中
  10. Android开发:keytool' 不是内部或外部命令 也不是可运行的程序
  11. Servlet的原理和基础使用
  12. 盘点2017 CES展会所有亮眼黑科技 (上)
  13. libfacedetection 人脸检测库的基本使用
  14. 数据挖掘实战(9.5)--使用神经网络识别MINIST数据集
  15. 不安分的 android 开发者(小程序初尝试)
  16. halcon提取区域的拐点、折点
  17. 微商代理系统APP软件
  18. 正版office 2007 简体中文专业版(附正版序列号)高速下载正版office 2007 简体中文专业版...
  19. 数字图像处理(2)正交变换
  20. 深度学习之目标检测(一)—— 目标检测算法介绍

热门文章

  1. IT人的八大修炼神器
  2. Worktile荣登2020中关村国际前沿科技创新大赛大数据与云计算领域TOP10
  3. 适合小团队协作、任务管理和进度跟踪的项目管理工具
  4. C语言循环选择还有,C语言第五讲,语句 顺序循环选择.(示例代码)
  5. 以Lazada为例,看电商系统架构演进
  6. 4、题目要求:读入N名学生的成绩,将获得某一给定分数的学生人数输出。 * * 输入格式:测试输入包含若干测试用例,每个测试用例的格式为 第1行:N 第2行:N名学生的成绩,相邻两数字用一个
  7. 《孤独是一个人的清欢》读书感悟
  8. C++中最好不要在构造函数和析构函数中调用虚函数!!!
  9. python 光标位置输入文字_Python 移动光标位置的方法
  10. 伦敦大学学院开源物体级语义SLAM!支持单/双目+LiDAR!