众所周知,数据库有四种隔离级别,那么这个隔离级别是什么用途呢?
大家可能对一个场景比较熟悉:做业务功能的时候,产品大大既要求保证业务的并发量,又要保证数据的安全性、一致性。而且还经常对较为复杂的这类场景感到头痛吧?
你可能会说不会头痛的 哈哈 优秀!
那么问题来了,在java代码或其他语言中保证安全性会使用到各种锁,那么数据库保证安全性的是什么呢?没错,你猜对了,就是锁,他也就是数据库隔离性实现的底层! 隔离就是为了安全!
PS: 我们只考虑 InnoDB 哈
共享锁(S Lock)
排他锁(X Lock)
共享锁允许多个事务读取同一行数据,可以理解为【共享读】;
排他锁只允许最多一个事务删除或更新同一行数据, 可以理解为【排他写】。
一个事务获取了一行的 S Lock 时,允许其他事务获取该行的 S Lock, 但不允许其他事务获取该行的 X Lock,
那么如果一个事务获取了一行的 X Lock 时,数据库允许其他事务获取到该行的 Slock吗?是否也需要等待?
上面说到,如果一个事务获取了一行的 X Lock 时,数据库允许其他事务获取到该行的 Slock吗?这个时候是不需要等待的,但是不需要加锁,因为这时候读取的是行的一个快照。
(因为快照是不会被修改的,所以快照是不会加锁的)这种快照读就是一致性非锁定读。每行会有很多快照,那么每次读取的都是哪个快照呢?
其实这就和隔离级别关系很大了,各个隔离级别对应读取的快照如下:
一般我们使用的都是一致性非锁定读,但是有些情况会去锁行,以保证数据逻辑一致性,这就是一致性锁定读。
InnoDB 提供了两种方式:
示例如下:
1 | select ... for update; |
next-key lock 可有效解决 幻读 的出现
RC时,用 for update 进行一致性锁定读某行,事务不关闭,其他事务是可以插入新的行的数据的,所以一致性锁定读期间的多次读取可能会出现 幻读。
next-key lock 是怎么解决幻读的呢?
RR级别下进行上述操作时,加的就是 next-key lock 间隙锁了。锁的范围是 2(正无穷大),当开启 for update 查询时,就对所有行加了 xlock,那么其他事务是不可能有插入数据的情况的。
他隔离级别最高,但串行化不是就说是多个事务的操作按顺序执行的。其实是InNoDB会为每个 select 加 lock in shared mode ,那么这些行的数据是肯定不会被获取到Xlock了,也就保证了串行化级别的可靠性。