InnoDB解决幻读的方案:LBCC+MVCC

为了解决以上隔离性引发的并发问题,数据库提供了事物的隔离机制。

  • read uncommitted(读未提交): 一个事务还没提交时,它做的变更就能被别的事务看到,读取尚未提交的数据,哪个问题都不能解决;

  • read committed(读已提交):一个事务提交之后,它做的变更才会被其他事务看到,读取已经提交的数据,可以解决脏读 ---- oracle默认的;

  • repeatable read(可重复读):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的,可以解决脏读和不可重复读 —mysql默认的;

  • serializable(串行化):顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。可以解决脏读、不可重复读和虚读—相当于锁表。

虽然serializable级别可以解决所有的数据库并发问题,但是它会在读取的每一行数据上都加锁,这就可能导致大量的超时和锁竞争问题,从而导致效率下降。所以我们在实际应用中也很少使用serializable,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

LBCC&MVCC


InnoDB默认的事务隔离级别是repeatable read(后文中用简称RR),它为了解决该隔离级别下的幻读的并发问题,提出了LBCCMVCC两种方案。其中LBCC解决的是当前读情况下的幻读,MVCC解决的是普通读(快照读)的幻读。至于什么是当前读,什么是快照读,将在下文中给出答案。

LBCC

LBCCLock-Based Concurrent Control的简称,意思是基于锁的并发控制。在InnoDB中按锁的模式来分的话可以分为共享锁(S)、排它锁(X)和意向锁,其中意向锁又分为意向共享锁(IS)和意向排它锁(IX)(此处先不做介绍,后期会专门出篇文章讲一下InnoDBMyisam引擎的锁);如果按照锁的算法来分的话又分为记录锁(Record Locks)、间隙锁(Gap Locks)和临键锁(Next-key Locks)。其中临键锁就可以用来解决RR下的幻读问题。那么什么是临键锁呢?继续往下看。

我们将数据库中存储的每一行数据称为记录。则上图中1、5、9、11分别代表id为当前数的记录。对于键值在条件范围内但不存在的记录,叫做间隙(GAP)。则上图中的(-∞,1)、(1,5)…(11,+∞)为数据库中存在的间隙。而(-∞,1]、(1,5]…(11,+∞)我们称之为临键,即左开右闭的集合。

记录锁(Record Locks)

对表中的行记录加锁,叫做记录锁,简称行锁。可以使用sql语句select ... for update来开启锁,select语句必须为精准匹配(=),不能为范围匹配,且匹配列字段必须为唯一索引或者主键列。也可以通过对查询条件为主键索引或唯一索引的数据行进行UPDATE操作来添加记录锁。

记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值