NoSQL数据库技术实战-第1章 NoSQL的数据一致性 传统关系型数据库的ACID
在看着章节的时候,我简单的回顾了一下关系型数据库的事务处理的ACID原则,其中原子性和持久性比较好理解。由于以前没有深入去研究。关于一致性和隔离性上我产生了疑问,在整理后分析如下:
一致性:书中所说的一致性是指数据库要保证事务处理前后,数据从一种一致的状态转移到另外一种一致的状态。书中举的例子是银行转账前后总账是不应该变化的。但是我困惑的是,转账前后总账的一致性应该是在应用程序中控制的,数据库怎么能保证呢?最后我的理解是,数据库本身不保证你的数据的一致性,但是它有一些处理,只要你的应用程序写法没有问题,就可以保证这种一致性。比如说在应用程序中,在一个事务中,进行一个转账:
A = A + 30;
B = B - 30;
如何保证这种一致性呢?
首先要保证原子性,要么全部成功,要么全部失败,否则就会造成数据的不一致。其次要保证读一致性,在事务中查询的数据都是事务开始那个时间点的状态,不会受到其他事务(甚至是在当前事务开始之后已经提交的事务)的干扰,个人觉得如果能保证这两点,就能保证这个转账操作的一致性。
当然,数据库本身也能提供一些一致性的处理,如主外键约束,check约束等。举例如,插入数据的时候会看外键在对应的表中是否存在,否则将执行失败。
所以,综合起来理解的说,数据库提供的一致性措施,我理解的暂时有读一致性和各种约束。
这是我读书的时候的理解,后来我在网上查阅了更多的资料,发现我的理解只是局部的。(甚至此书作者的理解也是错误的,如2.1.5中作者将一致性简单的理解为check约束的作用)其实主外键约束,check约束是数据库完整性的范畴(为什么完整性不再ACID中?我理解的是因为它只是在数据库执行的那一个时间点上检查一下数据的check约束,跟整个事务无关,所以不再ACID的范畴吧。)。而读一致性只是数据库一致性的一个重要的方面。
关于数据库一致性的正确理解应该是,数据库本身不能完全保证数据的一致性,只能提供一定的机制(NoSQL应该是连这种机制都没有)来保证一致性,如Oracle的语句级读一致性机制,事务的隔离级别(可以防止脏读,不可重复读,幻读等),事务级读一致性,回滚段机制等,都是保证读一致性的重要机制。
隔离性:
至于隔离性,书上说“不同的事务操作相同的数据时候,每个事务都有自己独立的工作空间”。我理解的是,不同的时候来操作相同的数据的时候,只能有一个事务在独占操作,另外的事务只能等待独占的那个事务执行commit或者rollback。后来我想,作者所谓的"操作"应该是包含了“更新”和“读取”,一个事务的更新操作在未提交之前不会被另外一个事务读取。这样就合乎情理了。
总结,隔离性就是说每个事务是相互隔离的,在没有执行完成(commit或者rollback)之前对外是不可知的。
我们习惯用自己的行为准则审视他人,并时刻准备加以指摘。