数据一致性详解

发布于 2021-07-28  1.03k 次阅读


首先,我们需要明确数据一致性的概念

 

数据一致性,就是当多个用户试图同时访问一个数据库,它们的事务同时使用相同的数据,可能会发生以下四种情况:丢失更新、未确定的相关性、不一致的分析和幻想读。

脏读、丢失修改、不可重复读、幻读 (并发事务下引起的问题)

搜集了一些资料,我发现,关于一致性这个概念,众说纷纭,而且许多答案将应用层的一致性与数据库层面的一致性混淆,由于本人才疏学浅,只能摘抄其他优秀答案:

如何理解数据库事务中的一致性的概念?

请看下面Wikipedia中关于数据库事务一致性的定义

Consistency ensures that a transaction can only bring the database from one valid state to another, maintaining database invariants: any data written to the database must be valid according to all defined rules, including constraints, cascades,triggers, and any combination thereof. This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct.

我对这段话的理解:

  • 数据库事务的一致性是指保证事务只能把数据库从一个有效(正确)的状态“转移”到另一个有效(正确)的状态。那么,什么是数据库的有效(正确)的状态?满足给这个数据库pred-defined的一些规则的状态都是 valid 的。这些规则有哪些呢,比如说constraints, cascades,triggers 及它们的组合等。具体到某个表的某个字段,比如你在定义表的时候,给这个字段的类型是number类型,并且它的值不能小于0,那么你在某个 transaction 中给这个字段插入(更改)为一个 String 值或者是负值是不可以的,这不是一个“合法”的transaction,也就是说它不满足我们给数据库定义的一些规则(约束条件)。
  • “This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct. ” 这又怎么理解呢?在数据库的角度来看,它只关心 transaction 符不符合定义好的规则,符合的就是legal的,不符合的就是illegal的。transaction 是否正确是从应用层的角度来看的,数据库并不知道你应用层的逻辑意义,它不保证应用层的transaction的正确性,这个逻辑正确性是由应用层的programmer来保证的。 这么说估计还是抽象,那么看下面我们熟知的转账的例子。
Table: Account
Columns:   Name(string), Balance(int)
约束条件:无

执行下面一个事务(A,B的初始余额均为1000,A给B转账1200)

1.  往表Account插入数据(A,1000)
2. 往表Account插入数据 (B,1000)
3. A给B转账1200,更新A的余额为-200,(A,-200)
4. B的余额增加1200,更新B的余额为2200(B,2200)

那么,数据库会认为这个 transaction 合不合法呢?也就是它满不满足我们给数据库的定义的规则呢?答案就是这个 transaction 是合法的,因为你定义表的时候没有约定 Balance 不能小于0。虽然我们从应用层的角度来看,这个transaction是不正确的,因为它不符合逻辑- balance不能小于0. 但我们数据库只关心你的 transaction 满不满足你的数据库定义的rule,不关心它具有什么业务的逻辑,这个业务逻辑是应该由应用层来理解并处理的。修改一下上面这个例子

Table: Account
Columns:   Name(string), Balance(int)
约束条件:Balance >= 0

执行下面一个事务(A,B的初始余额均为1000,A给B转账1200)

1.  往表Account插入数据(A,1000)
2. 往表Account插入数据 (B,1000)
3. A给B转账1200,更新A的余额为-200,(A,-200)
4. B的余额增加1200,更新B的余额为2200(B,2200)

注意,这里增加了约束条件Balance > 0, 上面的这个transaction违反了规则Balance>=0,那么这个事务数据库认为它是非法的,不满足一致性的要求,所以数据库执行这个事务会失败

最后请再认真研读一下链接 Consistency (database systems) 中的这段话。

This(Consistency)does not guarantee correctness of the transaction in all ways the application programmer might have wanted (that is the responsibility of application-level code) but merely that any programming errors cannot result in the violation of any defined database constraints.[1]

 


她喜欢所以就做咯