事务ACID —— 隔离性

什么是隔离性 ?

当两个或者多个事务并发访问(此处访问指查询和修改的操作)数据库的同一数据时所表现出的相互关系。
引用自 维基百科 —— ACID

多个事务单元之间的关系可以是以下四种:

  • 读读
  • 读写
  • 写读
  • 写写

序列化读写(Serializable)

上一篇事务ACID —— 一致性中说到,对同一数据访问时,为了强一致性的表现,就利用排他锁把一个有一个的事务排成一个队,这就是序列化读写级别

这个时候数据是非常安全的,不会出现混乱的情况。但是在这个级别的时候就会出现一个很严重的问题,没有并发,系统性能差。

可重复读(repeatable read)

为了解决序列化读写级别性能差,那么就有人想出来了,把排他锁变为读写锁。那么就可以提升系统的性能。

可重复读级别就是把序列化读写级别排他锁变为读写锁(读锁不能升级为写锁),这样就实现了读读并行。

可以从图二中看出,相对于图一,此时读读已经并行了。

读已提交(read committed)

为了进一步提升性能,人们就把可重复读级别读写锁(读锁不能升级为写锁)变更为读写锁(读锁可以升级为写锁)

那么我们可以看到下图,并发有进一步提升了。此时就实现了读读、读写并行(写读还不能并行)。

读未提交(Read uncommitted)

当只加写锁不添加读锁时候,看下图可以发现,读的顺序被上升了一格。

这种情况下,会出现幻读和脏读情况(读到写事务未提交的数据,写事务可能会出现回滚,那么读到的数据就是不存在的一个数据)。

总结

其实我们发现,隔离性的4中级别就是各种锁的不同组合变成了不同的隔离级别。
重另一个方面来说,隔离性就是以性能为借口,对一致性的一种破坏。

扩展,快照隔离级别(sanpshot isolation)/多版本并发控制(mvcc)

快照隔离级别的核心思路就是无锁编程,·copy on write·。

简单的说,将每次更新记录到一个回滚段之中。在写事务发生时,读事务进来,可以直接进入回滚段中读取数据。它的并行度可以达到读未提交级别,数据安全性可以达到可序列化读写级别

但是它也有一个缺点,就是会产生大量的二进制日志。