数据库ACID和mvcc
一、数据库的ACID性:
原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。
二、原子性
1.原子性:一个事务要么全部完成,要么失败。
2.原子性的核心是:利用一个undo日志来记录事务可以回滚的各个数据版本。即当目前执行的事务发生故障时,需要回滚,可以根据undo日志中的记录来知道事务回滚到哪一步停止。这样来保证事务由当下状态回滚到开始执行前的状态。
3.不要把原子性和一致性、隔离性混淆。
原子性并不能保证看不到数据的中间状态。而一致性和隔离性才可以保障用户是看不到数据的中间状态。
三、一致性。
一致性就是从一个状态转变到另外一个状态,没有数据的中间状态。
视点1代表读取事务开始之前的旧数据。
视点2代表读取事务执行中的中间状态的数据。
视点3代表读取事务结束之后的新数据。
在处理一致性问题时,有两种方法:上移视点3到视点1,读取旧数据;下移视点3到视点2,读取更新后的新数据。可见保证一致性就是保证不读取中间状态的数据。
四、隔离性。
隔离性就是以提高性能为目的,对一致性的破坏。
下面四种隔离级别,级别越来越低,对一致性的维护性越来越差,而并发性越来越高。
隔离性的四个隔离级别:
1.可序列化:事务隔离级别最高,并发性最差,利用排它锁实现。针对同一资源,将所有的请求事务进行排序,一一个顺序执行。最高限度的保证了数据的一致性。
2.可重复读:利用共享锁和排写锁实现。读读并行,禁止任何写事务并行。
3.读已提交:允许读后写并行。读到的任何数据都是提交的数据,避免读到中间的未提交的数据。但是无法避免不可重复读。因为读事务第一次读取数据之后,另一个写事务可能会修改此事务,导致读事务第二次读取数据和第一次所读到的不一样。但是这种场景并不是经常出现,系统的一致性可以接受,因此多数数据库的默认级别是读已提交。
4.读未提交:对所有事务只加写锁,不加读锁。即只有写写不可以并行。但是这回导致读事务读到一些中间状态的数据,即脏读。
五、MVCC
1.MVCC(多版本并发控制),是一种不利用锁机制实现的隔离级别,主要实现了在保证数据的一致性的前提下,实现了读写的并行。
之前提到的读已提交,虽然实现了读写并行,读未提交实现了写读并行,读写并行;但是两种隔离级别均没有保证数据的一致性,分别出现不可重复读和脏读。
2.mvcc的原理是给每一数据的更新都有一个版本号。当写事务正在进行时,此时过来一个读事务,读事务会首先生成一个版本号,即该事物想读取哪一个版本的数据。
然后,写事务更新数据,读事务读取之前相应版本的数据,而保证了不出现不可重复读和脏读的情况。
3.之前提到,保证数据一致性有两种方式,要么将读事务读取视点1的数据,要么读取视点2的数据。在mvcc中保证数据一致性的方法选择的是,读取视点1的数据,即读取的 是写事务开始之前的旧版本数据。