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 锁问题 (相同索引键值或同一行或间隙锁的冲突)的更多相关文章

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

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

  2. mysql按位的索引判断值是否为1

    DELIMITER $$ DROP FUNCTION IF EXISTS `value_of_bit_index_is_true`$$/*计算某个数字的某些索引的位的值是否都为1,索引类似1,2,3, ...

  3. MySQL记录锁、间隙锁、临键锁小案例演示

    生成间隙(gap)锁.临键(next-key)锁的前提条件 是在 RR 隔离级别下. 有关Mysql记录锁.间隙(gap)锁.临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文 ...

  4. Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁

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

  5. Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)

    Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...

  6. MySQL的间隙锁

    什么是间隙锁当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也 ...

  7. 了解下Mysql的间隙锁及产生的原因

    什么是间隙锁当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也 ...

  8. 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁

    你需要知道的 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁. 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁. 生活中的间隙 ...

  9. MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?

    大家好,我是小林. 是不是很多人都对 MySQL 加行级锁的规则搞的迷迷糊糊,一会是 next-key 锁,一会是间隙锁,一会又是记录锁. 坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如 ...

随机推荐

  1. Struts2 配置及运行时遇到问题

    1.java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilt ...

  2. 编写高质量代码改善C#程序的157个建议——建议39:了解委托的实质

    建议39:了解委托的实质 理解C#中的委托需要把握两个要点: 1)委托是方法指针. 2)委托是一个类,当对其进行实例化的时候,要将引用方法作为它的构造方法的参数. 设想这样一个场景:在点对点文件传输过 ...

  3. 关于Lucene分页标准

    public IEnumerable<SearchResult> Search(string keyword, string[] fieldNames, int pageSize, int ...

  4. linux学习之路(4)

    用户身份与文件权限 通过uid来区分:  管理员 UID 为 0:系统的管理员用户. 系统用户 UID 为 1-999: Linux 系统为了避免因某个服务程序出现漏洞而被黑客提 权至整台服务器,默认 ...

  5. angular HTML属性绑定

  6. VS Code基本使用

    1. Activity Bar 1.1 Explorer 1.1.1. OPEN EDITORS 所有在右侧编辑区打开的文件列表 1.1.2 {PROJECTNAME} 某个文件夹下的文件树 1.2 ...

  7. 6w4:第六周程序填空题1

    描述 下面程序的输出结果是: A::Fun C::Do 请填空: #include <iostream> using namespace std; class A { private: i ...

  8. 趣图:TCP 与 UDP 的差别

      趣图:程序猿和运维狗的工作日常…… 趣图:Java 和 PHP 之间的战斗

  9. 【ARC074F】Lotus Leaves 最小割

    Description 给你一个n*m网格图,有起点荷叶和终点荷叶,有中转荷叶,其他的格子没东西,一个荷叶可以跳到同一行或者列的另一个荷叶.问最多删掉几个中转荷叶能让起点终点不连通.如果不行输出-1. ...

  10. 【SSO单点系列】(7):CAS4.0 SERVER通过数据库方式认证用户

    在前几篇中有简单介绍服务端的认证方式,默认的是直接在 deployerConfigContext.xml 文件中 一个叫做 primaryAuthenticationHandler 的bean中配置. ...