共享锁和独占锁

  • 共享锁,英文名:Shared Locks,简称S锁。在事务要读取一条记录时,需要先获取该记录的S锁

  • 独占锁,也常称排他锁,英文名:Exclusive Locks,简称X锁。在事务要改动一条记录时,需要先获取该记录的X锁

假如事务T1首先获取了一条记录的S锁之后,事务T2接着也要访问这条记录:

  • 如果事务T2想要再获取一个记录的S锁,那么事务T2也会获得该锁,也就意味着事务T1T2在该记录上同时持有S锁

  • 如果事务T2想要再获取一个记录的X锁,那么此操作会被阻塞,直到事务T1提交之后将S锁释放掉。

如果事务T1首先获取了一条记录的X锁之后,那么不管事务T2接着想获取该记录的S锁还是X锁都会被阻塞,直到事务T1提交。

所以我们说S锁S锁是兼容的,S锁X锁是不兼容的,X锁X锁也是不兼容的,画个表表示一下就是这样:

兼容性

X

S

X

不兼容

不兼容

S

不兼容

兼容

对读取的记录加S锁

SELECT ... LOCK IN SHARE MODE;

对读取的记录加X锁

SELECT ... FOR UPDATE;

锁的粒度

我们前边提到的都是针对记录的,也可以被称之为行级锁或者行锁,对一条记录加锁影响的也只是这条记录而已,我们就说这个锁的粒度比较细;其实一个事务也可以在级别进行加锁,自然就被称之为表级锁或者表锁,对一个表加锁影响整个表中的记录,我们就说这个锁的粒度比较粗。给表加的锁也可以分为共享锁S锁)和独占锁X锁):

  • 给表加S锁

    如果一个事务给表加了S锁,那么:

    • 别的事务可以继续获得该表的S锁

    • 别的事务可以继续获得该表中的某些记录的S锁

    • 别的事务不可以继续获得该表的X锁

    • 别的事务不可以继续获得该表中的某些记录的X锁

  • 给表加X锁

    如果一个事务给表加了X锁(意味着该事务要独占这个表),那么:

    • 别的事务不可以继续获得该表的S锁

    • 别的事务不可以继续获得该表中的某些记录的S锁

    • 别的事务不可以继续获得该表的X锁

    • 别的事务不可以继续获得该表中的某些记录的X锁

InnoDB的间隙锁

InnoDB中,默认的隔离级别是可重复读,那是怎么解决幻读问题的呢?答案就是间隙锁

间隙锁会锁定一个范围,在该范围内,如果有事务想插入数据,需要等到间隙锁释放后才能插入。