MySQL的锁(行锁)

行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。

InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁,主要分为以下三类:

  1. 行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC、RR隔离级别下都支持。

默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

  1. 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁

在事务里使用select * from stu where id=1 lock in share mode;

会产生行锁和表的意向锁。

共享锁和共享锁兼容。

id为1的加了行锁之后,可以对id=3的进行更新操作

update stu set name='java' where id=3;

如果更新id=1的,就会处于阻塞状态。

  1. InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。

name字段没有索引的情况下,执行

begin;

update stu set name='php' where name='java';

在另外的事务中

begin;

update stu set name='spring' where name='tom'; 会被锁住,说明上面的执行升级为表锁了。

  1. 间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR隔离级别下都支持。

默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

(1)索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。

在唯一索引上,更新一条不存在的记录

begin;

update stu set name='tomcat' where id=5;

这个时候,3和8之间(不包含3,8)就会被锁住GAP,

使用insert语句进行验证

begin;

insert into stu values(7, 'springboot', 7); 会一直堵塞在那里,直到左边的事务提交。

(2)索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。

先在age上创建普通索引(非唯一索引)

create index idx_age on stu(age);

(3)索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。

  1. 临键锁(next-key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。

在并发访问时,解决数据访问的一致性、有效性问题。分全局锁、表级锁、行级锁。

全局锁是对整个数据库实例加锁,加锁后整个实例就处于只读状态,性能较差,数据逻辑备份时使用。

表级锁是操作锁住整张表,锁定粒度大,发生锁冲突的概率高,分为表锁、元数据锁,意向锁。

行级锁是操作锁住对应的行数据,锁定粒度最小,发生锁冲突的概率最低,分为行锁、间隙锁、临键锁。

相关推荐
灵晔君12 分钟前
【MySQL】数据库基础
数据库·mysql·adb
香蕉大香蕉(06敬畏市场)32 分钟前
MySQL 单点详解(03)
java·数据库·mysql·面试·八股·大厂实习
赤生云电竞33 分钟前
云游戏边缘节点部署:机房选址与网络拓扑优化实践——接入延迟、VXLAN与GPU虚拟化选型
数据库·游戏
Y002 小时前
PostgreSQL 权限管理踩坑记:从 42501 到默认权限和 RLS
数据库·postgresql
呆萌很2 小时前
达梦(DM8)数据库常用SQL
数据库·sql
跟太阳说早安2 小时前
极简数据库SQL
数据库·sql
前端 贾公子2 小时前
第 5 章:Codex 从可运行程序到可交付工具
java·前端·数据库
杨云龙UP2 小时前
MySQL 主从复制管理:暂停、恢复、清理主从关系及命令执行位置
运维·数据库·mysql·主从配置·主从命令·reset replica·清除复制
yzs873 小时前
openGauss branch diff能力解析
数据库·oracle
霂鳯3 小时前
新手勇闯网络安全 | MySQL复习
mysql·安全·web安全