云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

数据库中各种锁(数据库中的锁包括什么)

jxf315 2025-07-01 20:48:45 教程文章 4 ℃

在MySQL InnoDB中有7种锁:

  1. 共享锁(S锁)、排他锁(X锁)
  2. 意向锁(Intention Locks)
  3. 记录锁(Record Locks)
  4. 间隙锁(Gap Locks)
  5. 临键锁(Next-Key Locks)
  6. 插入意向锁(Insert Intention Locks)
  7. 自增锁(Auto-inc Locks)

这7种锁,锁的范围、锁的类型都不同

按锁的粒度来分,分为表锁、行锁、范围锁(gap间隙锁)

按锁的类型来分,分为共享锁、排他锁、意向锁


锁的粒度

  • 表锁:表级别是对操作的整张表加锁,锁定颗粒度大,资源消耗小,不会出现死锁,但并发度低


  • 行锁:MyISAM引擎只支持表锁,InnoDB支持行锁级别,锁粒度小并发高,持有锁资源越多,消耗也多,可能出现死锁。


  • 范围锁:范围锁是锁住一个范围,锁记录之前的范围,是一个开区间,目的是避免另一个事务在这个区间上插入新记录


锁的类型

  • 共享锁(S)也叫是读锁,读和读之间允许并发,读和写之间不能并发;


  • 排他锁(X)是写锁,读和写之间不能并发,写和写之间也不能并发。表和行两个粒度均有共享锁、排他锁类型。


  • 意向锁是表锁的一种,为了解决表锁与行锁冲突判断效率问题产生的。


试想下面场景,有两个事务T1、T2

T1: 锁住表中的一行,只能读不能写(行级读锁)

T2:申请整个表的写锁(表级写锁)

如果T2申请成功,则能任意修改表中的一行,但这与T1持有的行锁是冲突的。所以数据库要识别这种冲突,让T2的申请的锁被阻塞,直到T1释放行锁。

怎样识别出这种冲突,最简单办法是遍历每一行判断是否被行锁锁住,这种办法效率很低。

innodb想到使用意向锁来解决这个问题,T1在加行级锁之前,给表申请加上一个意向共享锁(IS)。如果发现表上有意向共享锁,说明表中行被共享行锁锁住了,因此T2申请表写锁会被阻塞。


锁的兼容性分析如下表:

横轴表示已持有的锁,纵轴表示尝试获取的锁。1表示成功(即兼容,正常进行下一步操作),0表示失败(即冲突,阻塞住当前操作)

兼容性

IX

IS

X

S

IX

1

1

0

0

IS

1

1

0

1

X

0

0

0

0

S

0

1

0

1

总的来说,排他锁和共享锁、意向锁会发生冲突并导致阻塞,而意向锁之间不会冲突。共享锁和共享意向锁则不会发生冲突。


如何加锁:

  • 普通select...查询(不加锁)
  • 普通insert、update、delete...(开启事务,隐式加写锁)
  • select..lock in share mode(加读锁)
  • select ... for update (加写锁)

解锁:

提交或回滚事务、kill阻塞进程


锁的类型分类

记录锁是行锁,仅仅是锁住一行,会阻塞其他事务对其插入、更新、删除

select id from t where id = 1 for update


自增锁是一种表级别的锁,专门针对自动递增的列,是为了防止其他事务在两次连续的insert中间插入一条记录,因为id自增列取值是连续的,如果不加AI锁,第一次insert值是5,第二次insert值可能不是6,中间被插入其他记录,值变成7。

对应事务来说很奇怪,明明连续插入了两条数据,自增列却不是连续递增。

start transaction
    insert t1 values(a.b,c);
    insert t1 values(a,b,c);
    select a from t1 where xxx
commit


间隙锁(gap lock)是锁住一个范围,不包含记录本身,目的是避免另一个事务在这个范围内插入新记录。


临键锁(next-key lock)是间隙锁与记录锁组合,是在某条记录以及这条记录前面间隙上加锁。


插入意向锁(insert intension lock)是专门针对插入操作,目的是为了提高并发插入能力。多个事务申请意向锁时,只要不是插入在范围内相同位置不需要阻塞等待,在同一索引、同一范围区间内可以并发插入。

普通gap lock不允许在(上一条记录,本记录)范围内插入数据

插入意向锁允许在(上一条记录,本记录)范围内插入数据


是否加gap锁和事务隔离级别密切相关,如果事务的隔离级别是RC,允许幻读,则不需要锁范围。


gap锁往往是针对非唯一索引,如果通过主键索引、或者非主键索引,可以明确地定位到哪一条或者哪几条记录的修改,则不需要锁范围。

最近发表
标签列表