锁与索引和释放锁时机

简介: 【8月更文挑战第1天】

在MySQL的InnoDB引擎里,锁是借助索引来实现的,加锁锁住的其实是索引项,更加具体的说,是锁住了叶子节点

引出的问题:

  1. 一个表有很多索引,锁的是哪个索引呢?
    答案是 查询最终使用的索引
  2. 万一查询没有使用任何索引呢?
    那么就会锁住整个表,此时退化为表锁。
  3. 如果查询条件的值不存在,怎么锁?比如SELECT * FROM your_tab WHERE id = 15 FOR UPDATE

InnoDB引擎会利用最接近15的相邻的两个节点,构造一个临键锁
如果这个时候别的事务想要插入一个id=15的记录,就不会成功

  1. 那么范围查询呢?
    利用索引上的数据,构建一个恰好能够装下这个范围的临键锁,例如 :SELECT * FROM your_tab WHERE id > 33 FOR UPDATE,InnoDB引擎会构造一个(33,supremum]的临键锁,锁住整个范围。supremum是MySQL认为的一个虚拟的最大值

通过上述可以得出一个结论:锁和索引密切相关

学习锁的时候容易有一个误区:认为锁是在语句执行完毕之后就立刻释放掉。
事实上,锁是在整个事务结束之后才释放的。也就是说,当一个事务内部给数据加上锁之后,只有执行Rollback或Commit的时候,锁才被释放掉

目录
相关文章
|
3月前
|
Java
锁对象
锁对象
129 73
|
3月前
|
NoSQL 前端开发 Java
【幂等性大坑】事务提交前释放锁导致锁失效问题
在事务中,使用了 Redis 分布式锁.这个方法一旦执行,事务生效,接着就 Redis 分布式锁生效,代码执行完后,先释放 Redis 分布式锁,然后再提交事务数据,最后事务结束。如果是表单重复提交场景,可以尝试给“订单号”等有唯一性的字段加唯一索引,这样重复提交时会因为唯一索引约束导致索引失效。5、如果表的一个字段,要作为另外一个表的外键,这个字段必须有唯一约束(或是主键),如果只是有唯一索引,就会报错。2、创建唯一约束,会自动创建一个同名的唯一索引,该索引不能单独删除,删除约束会自动删除索引。
【幂等性大坑】事务提交前释放锁导致锁失效问题
|
7月前
|
Java 编译器
多线程(锁升级, 锁消除, 锁粗化)
多线程(锁升级, 锁消除, 锁粗化)
61 1
|
安全
顺序锁seqlock
顺序锁seqlock
101 0
|
7月前
|
Java 编译器 程序员
synchronized 原理(锁升级、锁消除和锁粗化)
synchronized 原理(锁升级、锁消除和锁粗化)
|
Java
加锁和释放锁的原理
当方法执行完后或者抛出异常后,都会释放锁
67 0
锁消除、锁粗化、锁升级区别与联系
锁消除、锁粗化、锁升级区别与联系
锁消除、锁粗化、锁升级区别与联系
|
缓存 NoSQL Redis
什么是自旋锁 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。
什么是自旋锁 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。
240 0
什么是自旋锁 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。
并发锁(一):为什么要加锁
并发锁(一):为什么要加锁
168 0
并发锁(一):为什么要加锁
|
设计模式 安全 算法
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)