lock in share mode 和 select for update

2018年07月11日 01:57:58 道不虚行只在人 阅读数 146
 
 版权声明:欢迎转载,请注明出处 https://blog.csdn.net/xinzhongtianxia/article/details/80994259

同步发表于:http://blog.lanjingdejia.com/articles/2018/07/11/1531245873812.html
许多同学或应该都听过"select … lock in share mode" 和 “select … for update”,但是或多或少会有以下几个疑问:

  1. 这俩货是什么含义?
  2. 和普通的select有什么区别呢?
  3. 什么场景下用?用哪个?

含义

我们直接从mysql官网上看它们的定义:

SELECT … LOCK IN SHARE MODE

Sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits. If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values.

翻译一下:在你正在读的行设置一个共享锁,其他session也可以读这些行,但是直到你读完这些行,事务提交释放锁之后,其他sesstion才能更改这些行。如果你要读取的行正在被其他session修改,那么读取会卡住,直到其他session修改完毕,读取才能继续,并且读到的是最新版本的数据。

SELECT … FOR UPDATE

For index records the search encounters, locks the rows and any associated index entries, the same as if you issued an UPDATE statement for those rows. Other transactions are blocked from updating those rows, from doing SELECT … LOCK IN SHARE MODE, or from reading the data in certain transaction isolation levels.

翻译一下:对于select的数据,会对这些行及其相关行加锁,效果和用update更新这些行时是一样的。其他对这些数据进行操作,无论是update也好,上面提到的SELECT … LOCK IN SHARE MODE也好,甚至在某些事务隔离级别下读取这些数据也好,所有这些操作都会被阻塞。

通俗一点

lock in share mode能保证读到的一定是最新的值,而且保证读的过程中不会被其他session修改。因为加的是共享锁,所以多个session同时lock in share mode时都可以读到数据。
select for update更严格一些,加的是排它锁(根据情况,有时还会加间隙锁),会阻塞住所有其他session对该数据的操作。

和普通的select的区别

mysql(InnoDB)的select有三种:

  • 啥也不加的普通的select
  • select … lock in share mode
  • select … for update

上面提到的共享锁、排它锁等等,这些锁对普通的select是没有用的,普通的select是永远不会被阻塞的。下面举例说明。

普通select和lock in share mode的区别

  1. session A正在修改(update或者delete)某一行数据,如果这时session B进行普通的select,session B是不会被阻塞的,且读到的是session A修改之前的数据。如果这时session C进行select … lock in share mode,那么session C将会阻塞,直到session A所在的事务提交(或者回滚释)放锁之后,session C才会继续进行,且读到的使session A修改过后的数据。
  2. session A 正在进行普通的select,如果这时session B 进行update操作,那么session B不会被阻塞。但是如果session A进行的是select … lock in share mode,那么session B的update操作会被阻塞,直到session A提交之后,session B才能继续进行。

普通select和select for update的区别

区别同上

lock in share mode和select for update的区别

  1. session A正在 lock in share mode, 此时session B 进行lock in share mode 操作不会被阻塞,但是如果此时session C进行select for update的话,就会被阻塞。
  2. 如果session A 正在select for update,如果此时session B 进行lock in share mode, 那么session B会被阻塞,如果此时session C也进行select for update操作,那么session C也会被阻塞。

使用场景

select … lock in share mode的使用场景

引用mysql官网的例子,有两张表:parent表和child表,向child表插入数据时,要保证child的parent在parent表中存在,删除parent表时,会将parent以及该parent的child都删掉。一般的操作是先select,得到parentId,然后向child中插入一条数据(关联parentId),但是这样是有问题的,如果select之后,插入之前,另一个session将parent删掉了,那么向child表中插入的数据并不会受到影响,最终造成该child没有parent的状况。
根据上面提到的特性,select时用select … lock in share mode就能解决这个问题。其实select … lock in share mode 在平时用到的场景很少很少,用的比较多的还是select … for update。

select … for update的使用场景

账户表中有一个字段money,取出来后,将money更新(比如加上一个值)后再存进去。对于这个场景,如果两个session同时select,比如都取出来的是100,然后都加30, 都变成130,然后都update money,最终money的值是130,与预期的160不符。这个时候用select … for update 就能完美解决这个问题,这时因为两个session不能同时select … for update。

思考

上述select … for update的场景如果使用select … lock in share mode会怎样?
答案是,会很大概率造成死锁,造成死锁的原因是:session A和session B同时select lock in share mode, 这时都未提交事务,session A 继续执行update操作,此时因为session B事务还没提交,锁还没释放,所以session A的update操作会被阻塞,等待session B释放锁,同样的,session B此时也在等待session A提交事务释放锁,这就发生了死锁。
所以lock in share mode 使用时要仔细检查,确认该场景是否真的适用且不会发生死锁。

lock in share mode 和 select for update的更多相关文章

  1. 深入理解SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE

    概念和区别 SELECT ... LOCK IN SHARE MODE走的是IS锁(意向共享锁),即在符合条件的rows上都加了共享锁,这样的话,其他session可以读取这些记录,也可以继续添加IS ...

  2. SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE locks在RR模式下可以看到最新的记录

    14.5.2.4 Locking Reads 锁定读: 如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护. 其他事务可以修改或者删除你刚查询相同的记录 ...

  3. [MySQL] 行级锁SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE

    一.译文 翻译来自官方文档:Locking Reads If you query data and then insert or update related data within the same ...

  4. SELECT LOCK IN SHARE MODE and FOR UPDATE

    Baronwrote nice article comparing locking hints in MySQL and SQL Server. In MySQL/Innodb LOCK IN SHA ...

  5. MySql事务select for update及数据的一致性处理讲解

    MySQL中的事务,默认是自动提交的,即autocommit = 1: 但是这样的话,在某些情形中就会出现问题:比如: 如果你想一次性插入了1000条数据,mysql会commit1000次的, 如果 ...

  6. Select for update/lock in share mode 对事务并发性影响

    select for update/lock in share mode 对事务并发性影响 事务并发性理解 事务并发性,粗略的理解就是单位时间内能够执行的事务数量,常见的单位是 TPS( transa ...

  7. 转 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 ...

  8. Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  9. 浅谈select for update 和select lock in share mode的区别

    有些情况下为了保证数据逻辑的一致性,需要对SELECT的操作加锁.InnoDB存储引擎对于SELECT语句支持两种一致性的锁定读(locking read)操作. . SELECT …… FOR UP ...

随机推荐

  1. Java 待学习知识

    Java 工厂模式和策略模式 Java 面向对象与面向接口的设计模式 Java 六大设计原则 - 单一职责原则 设计模式之禅     大话设计模式

  2. 解决VM Workstation安装VMware Tools显示灰色的办法

    其实虚拟机用了好多次了,但是每次使用配置时还是忘这忘那的,这里就简单地再啰嗦下了. 解决办法如下: 1.关闭虚拟机: 2.在虚拟机设置分别设置CD/DVD.CD/DVD2和软盘为自动检测三个步骤: 3 ...

  3. 使用vue搭建应用一入门

    1.准备 安装nodejs,配置环境变量 安装了nodejs,也就安装了npm 安装webpack npm install webpack -g 安装vue脚手架项目初始化工具 vue-cli npm ...

  4. Docker Compose 部署Nginx服务实现负载均衡

    Compose简介: Compose是Docker容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器,使用Docker Compose,不再需要使用shell脚本来启动容器.Comp ...

  5. hbase 安装(集群模式)

    环境:jdk 1.8 + hadoop2.7.6+zookeeper3.4.9+centos7 一.安装zookeeper(集群模式) 0.安装机器 ip                       ...

  6. SACD-ISO音频镜像播放方式

    SACD-ISO 音频文件不需要解压也不需要挂载光盘,可以直拖入播放器播放. 播放器下载 foobar2000https://www.foobar2000.org/download 解码插件下载 Su ...

  7. 异常处理和UDP Socket套接字

    一.异常处理 1.什么是异常处理: 程序在运行过程中出现了不可预知的错误,并且该错误没有对应的处理机制,那么就会以异常的形式表达出来,造成的影响就是整个程序无法再正常进行. 2.异常的结构: 1.异常 ...

  8. C语言:求π

    1835: 圆的面积 本题的关键在于如何求π: 今天先给给大家介绍一种针对本题的方法——利用反三角函数求π. 在高数中arcsin(0)=arccos(1)=π,不过编译器中并没有arcsin和arc ...

  9. LInux基础(04)项目设计一(理解链表管理协议的代码架构)

    要设计好一个项目必须要有一个健全的代码框架 一个结构体内有数据域和处理数据的函数指针, 先实现管理链表的函数 增加节点  删除节点  清空链表  遍历节点对每个节点进行操作 再实现协议的注册 把对象s ...

  10. expect——通过编写自动化脚本实现信息交互(整理)

    本文简要介绍了expect工具语言的功能.用法,并以实例来具体说明 expect是什么 Expect是一个免费的编程工具语言,用来完成通信过程中的交互式任务,而无需人的干预. 通过shell虽然可以实 ...