1.使用相同索引键值的冲突

  由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的。设计时要注意
  例如:city表city_id字段有索引,Cityname字段没有索引:

会话1

会话2

SET autocommit=0;

SET autocommit=0;

SELECT * FROM city WHERE city_id=14 AND Cityname='深圳' FOR UPDATE;

city_id      country_id        cityname CityCode

14     2       深圳         001

会话2与会话1访问的是不同的记录,但是因为使用了相同的索引值,所以需要等待锁

SELECT * FROM city WHERE city_id=14 AND Cityname='长沙' FOR UPDATE;

等待...

 2.使用不同索引键值但是同一行的冲突 

  当表有多个索引时候,不同的事务可以使用不同的索引锁定不同的行,无论什么索引,innodb都会使用行锁来对数据加锁。
  例如city表city_id字段有主键索引,CityCode字段有普通索引:

会话1

会话2

SET autocommit=0;

SET autocommit=0;

SELECT * FROM city WHERE city_id=14  FOR UPDATE;

city_id      country_id        cityname CityCode

14     2       深圳         001

该记录没有被索引,所以可以获得锁

SELECT * FROM city WHERE  CityCode='002' FOR UPDATE;

city_id      country_id        cityname CityCode

15     2       长沙         002

由于该记录被会话1锁定,所以需要等待

SELECT * FROM city WHERE  CityCode='001' FOR UPDATE;

等待...

3. 创建了索引,但使用的是表锁
  在前面章节说过,创建了索引但不走索引的情况,这种情况下innodb将使用表锁,而不是行锁,因些分析锁冲突时,还需检查sql的执行计划,以确认是否真正使用了索引。

4. 间隙锁(next-key锁) 并发下要重点考虑

当我们用范围条件而不是相等条件检索数据,并请求共享或排它锁时,innodb会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录就叫做"间隙锁"  比如city表数据分布如下:

  如果查询使用如下sql
  select * from city where city_id>100 for update;

  这就是一个范围条件的检索, innodb不但会对符合条件的101的记录加锁,也会对city_id大于101(虽然记录并不存在)的"间隙"加锁。使用间隙锁的目的是为了防止幻读,以满足相关的隔离级别。关于幻读查看"sql 开发进阶篇系列 6 锁问题(事务与隔离级别介绍)"
很明显,在使用范围条件的检索记录时, 会阻塞符合条件范围内键值的并发插入,往往造成严重的锁等待。在实现业务中尽量使用相等条件来检索数据。还需注意如查使用相等条件检索的数据不存在时,也会加间隙锁。
  为了防止幻读,mysql隔离级别必须是REPEATABLE-READ和Serializable。REPEATABLE-READ也是默认的隔离级别。

会话1

会话2

SELECT @@tx_isolation

@@tx_isolation

REPEATABLE-READ

SELECT @@tx_isolation

@@tx_isolation

REPEATABLE-READ

SET autocommit=0;

SET autocommit=0;

-- 当前会话对不存在的记录加 for update;

SELECT * FROM city WHERE city_id=102 FOR UPDATE;

如果这里插入的值>=102就会出现阻塞

INSERT INTO city VALUES(200,2,'江门','005')

错误代码: 1205

Lock wait timeout exceeded; try restarting transaction

ROLLBACK;

INSERT INTO city VALUES(200,2,'江门','005')

共 1 行受到影响

mysql 开发进阶篇系列 10 锁问题 (相同索引键值或同一行或间隙锁的冲突)的更多相关文章

  1. mysql 锁问题 (相同索引键值或同一行或间隙锁的冲突)

    1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...

  2. mysql 开发进阶篇系列 55 权限与安全(安全事项 )

    一. 操作系统层面安全 对于数据库来说,安全很重要,本章将从操作系统和数据库两个层面对mysql的安全问题进行了解. 1. 严格控制操作系统账号和权限 在数据库服务器上要严格控制操作系统的账号和权限, ...

  3. mysql 开发进阶篇系列 46 物理备份与恢复( xtrabackup的 选项说明,增加备份用户,完全备份案例)

    一. xtrabackup 选项说明 在操作xtrabackup备份与恢复之前,先看下该工具的选项,下面记录了xtrabackup二进制文件的部分命令行选项,后期把常用的选项在补上.点击查看xtrab ...

  4. mysql 开发进阶篇系列 47 物理备份与恢复(xtrabackup 的完全备份恢复,恢复后重启失败总结)

    一. 完全备份恢复说明 xtrabackup二进制文件有一个xtrabackup --copy-back选项,它将备份复制到服务器的datadir目录下.下面是通过 --target-dir 指定完全 ...

  5. mysql 开发进阶篇系列 42 逻辑备份与恢复(mysqldump 的完全恢复)

    一.概述 在作何数据库里,备份与恢复都是非常重要的.好的备份方法和备份策略将会使得数据库中的数据更加高效和安全.对于DBA来说,进行备份或恢复操作时要考虑的因素大概有如下: (1) 确定要备份的表的存 ...

  6. mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)

    1. innodb_lock_wait_timeout mysql 可以自动监测行锁导致的死锁并进行相应的处理,但是对于表锁导致的死锁不能自动监测,所以该参数主要用于,出现类似情况的时候等待指定的时间 ...

  7. mysql 开发进阶篇系列 14 锁问题(避免死锁,死锁查看分析)

    一. 概述 通常来说,死锁都是应用设计问题,通过调整业务流程,数据库对象设计,事务大小,以及访问数据库的sql语句,绝大部分死锁都可以避免,下面介绍几种避免死锁的常用 方法. 1. 在应用中,如果不同 ...

  8. mysql 开发进阶篇系列 15 锁问题 (总结)

    1. innodb 行锁是基于索引实现的,如果不通过索引访问数据,innodb会使用表锁. http://www.cnblogs.com/MrHSR/p/9376086.html 2. Innodb ...

  9. mysql 开发进阶篇系列 13 锁问题(关于表锁,死锁示例,锁等待设置)

    一. 什么时候使用表锁 对于INNODB表,在绝大部分情况下都应该使用行锁.在个别特殊事务中,可以考虑使用表锁(建议). 1. 事务需要更新大部份或全部数据,表又比较大,默认的行锁不仅使这个事务执行效 ...

随机推荐

  1. #2019-2020-4 《Java 程序设计》第九周总结

    2019-2020-4 <Java 程序设计>第九周知识总结 第十一章:JDBC与MySQL数据库 11.1 MySQL数据库管理系统 下载安装: 11.2 启动MySQL数据库服务器 具 ...

  2. #2019-2020-4 《Java 程序设计》第八周总结

    2019-2020-4 <Java 程序设计>第八周知识总结 第15章:泛型与集合框架 一.泛型 1.泛型(Generics)是可以建立具有类型安全的集合框架,如链表.散列映射等数据结构: ...

  3. 每日一练ACM

    2019.04.15 第1000题:A+B Problem Problem DescriptionCalculate A + B. InputEach line will contain two in ...

  4. 查看进程被哪台电脑的哪个进程连接(netstat)

    1.netstat -ano|findstr 进程号,找出连接该进程A所有的ip(可以看到该进程的端口号和连接进程的端口号): 2.到连接该进程的电脑上,打开cmd命令行,输入netstat -ano ...

  5. qt网络通讯出现中文乱码

    转自:https://blog.csdn.net/i_fuqiang/article/details/21174227 发送: void TcpS::btn_send() { QByteArray d ...

  6. 在ExtJS中查看视频

    listeners: { render: function() { win.update( '<video src="' + path+ '" width="100 ...

  7. .Net QQ互联教程

    qq互联只需要备案即可申请,申请成功后可以到qq互联官网查看教程,本站开始想使用js的教程但是由于本站需要绑定本站的账号用js教程无法完成,所以使用原始的oauth2.0来完成. 申请qq互联接口 q ...

  8. sublime text3如何在浏览器预览?

    插件: view-in-browser CTRL + ALT + V 打开浏览器 默认打开firefox,settings里面可修改. Sublime Text - View In Browser V ...

  9. RSA 前段加密 java 后台解密 已调试通过

    本人整理网上的.好多网上的调不通.在这里把调试好的贴出来. 1.   异步获取公钥(后台获取):你也可以将公钥串写在页面上: var publicKey = null; $.ajax({ url: c ...

  10. java 基础复习

    最近准备阿里巴巴的面试,被提到需要一个比较好的java能力,因此花了点时间,再次把JAVA看了一遍,其中的某些重点记录下来,以便以后复习. (1)& 和&& 的区别 (2)排序 ...