数据库事务隔离性

这篇主要介绍数据库事务中的隔离性,全篇从大概念入手到数据库事务隔离性的一般设计理念以及要面对的挑战。

本篇纯码字,不过其中有区分很多博客上易混淆且常出错的概念,欢迎交流。

一,理解事务

事务是由一系列对系统中数据进行访问与更新的操作组成的一个程序执行逻辑单元。在数据库中,事务被赋予了更重要的意义:一方面数据库肯定要面对多并发的情况,多个应用程序同时发来请求,事务在这些应用程序中起到隔离的作用;另一方面事务也提供了回滚的能力,可以快速应对各种原因造成的事务失败,在尽量保证可用性的同时,提供服务的数据一致性。

假如,你想使用一个数据库服务。最开始你使用的是单机数据库(集中式系统),你开始设计你的数据库如何处理数据

经过大量的设计实践,我们总结了数据库事务的以下特性:我的这一系列操作希望给他封装成一个整体,要不全完成,要不不完成(原子性);事务如果因为什么原因中断,我们希望数据库的状态也是稳定一致的,而不是一半事务操作完的数据残留在数据库中(一致性);在并发环境中,各个事务即使操作相同数据也不相互干扰(隔离性);而且事务一旦提交,对数据库的改变我们希望是永久性的(持久性)

二,事务的隔离级别

我们着重关注在这里的事务隔离性(ACID中的隔离性)

并发环境中,事务不能互相干扰。为了保证不同事务操作数据时和其他事务是隔离的,互不干扰,在标准SQL规范中,定义了四个事务隔离级别,不同的隔离级别对事务的处理不同:

读未提交,读已提交,可重复读,串行化

同样是处理高并发,这和我们处理后端逻辑加锁其实很相似

这四种隔离级别隔离强度依次递增,理解隔离级别最好的方式是理解下一个隔离级别做了哪些措施解决了当前的哪些问题,

读未提交

读未提交是最低的隔离级别,也叫未授权提交,这种隔离级别指的是,一个事务在执行数据读写操作而且未提交时,其他事务可读取相同的数据。即一个事务不会阻塞其他事务的读,想一想这里会有什么问题?答案:这里会引起脏读,即因为读到执行事务尚未提交的数据,一旦执行事务发生回滚,数据复原,其他事务读到的数据就是错误的的,也就是脏数据。这种情况很容易发生,所以一般不会把读未提交作为高并发设计中的隔离级别。

读已提交

读已提交解决了上一个隔离级别的脏读问题,做法即在事务执行的过程中,数据加锁不让其他事务读,即可以解决脏读的问题,对于DBA来说只需要知道提升到READ_COMMITED隔离级别就可以防止脏读,其实不同数据库厂商对于脏读的处理细节也不相同,不过一般都是通过记录回归段实现一执行读取。不过,读已提交对于高并发高峰时处理仍然会有问题:因为执行事务提交之后改变了值,这个时候可能会插进另一个执行事务又改变了值,我的线程读了两次就读到不一样的值

可重复读

解决不可重复读的隔离级别是可重复读,对应的改进是InnoDB存储引擎利用版本号乐观锁加了行锁处理,这样锁加在索引记录里,保证了其他事务读到的数据是MVCC确定的实时的数据,不会出现两次读不同值的迷惑数据。理解重复读是因为多个执行事务多次修改,其他事务读时会出错。而加了行锁之后,仍然不能保证的是执行事务在读取某个范围内的记录时,另外一个事务在这个范围内插入了新的记录,当之前的事务再读改范围的记录时,会产生幻行。

脏读/不可重复读/幻读

这里着重拿出幻读解释下和脏读,不可重复读的不同,脏读是其他事务的读操作未阻塞,可以读到脏数据。读操作加锁之后,事务不能读取其他事务操作数据过程中的中间值,而同一个事务多次读了多事务修改的数据还会造成读到的值不一样,这个时候加了行锁保证读到数据的唯一性。但由于只加了行锁,不能保证范围操作时所有的数据不被其他事务修改。值得指出的是幻读并不是其他事务修改了当前事务操作的值,而是由于范围查询,B+树不能锁定索引与索引之间的范围数值而可能导致的多一条数据的情况。

可串行化

最后一个隔离级别是可串行化,通过间隙锁锁定索引与索引之间的空间,相当于扩大了锁的范围来避免幻读的情况。也是最高的隔离级别,这种间隙锁肯定比行锁更重,也更能保证事务间的隔离性。

三,分布式事务的处理

当数据库处理数据越来越多,你原有的系统无法承载,这个时候就需要扩容。扩容一般由两种方式,一种是纵向扩展,即升级配置,增加现有节点的内存CPU;另一种是横向扩展,增加节点数量,负载更多的数据。

这两种各有千秋,不过分布式需求是永恒的,如何解决分布式数据库的事务隔离性?我们在保证单机事务隔离性的基础上,把事务合理切分成小事务,并通过BASE设计,各集群间replication达到最终一致性,所以能让使用者几乎感受不到分布式和单机的差别,不过一个大型分布式数据库还是需要设计来保证分片分区,以及选主的方式等。

总结下,我认为分布式事务处理是建立在集中式数据库服务事务之上的性质。在ACID之上并合理切分数据之后拓展了BASE为代表的分布式设计规则,通过二提交,paxos等方法维护分布式系统的一致性协议。针对于数据库来说一般是通过二提交保证一致性,并通过自身的主从框架设计实现数据可扩展。

 

参考文献:

1. 从PAXOS到zookeeper分布式一致性原理实践--倪超

2. mysql性能调优与框架设计

 

 

 

你可能感兴趣的:(后台相关)