我正在阅读有关数据库的 ACID 属性的信息。原子性和一致性似乎密切相关。我想知道是否有任何情况下我们需要只支持原子性而不支持一致性,反之亦然。一个例子真的很有帮助!
5 回答
它们有些相关,但有细微的差别。
原子性意味着您的交易要么发生,要么不发生。
一致性意味着诸如参照完整性之类的事情被强制执行。
假设您开始交易以添加两行(形成单个银行交易的贷方和借方)。这个的原子性与数据库的一致性无关。这意味着将添加两行或两行都不会添加。
在一致性方面,假设您有一个来自orders
to的外键约束products
。如果您尝试添加一个引用不存在产品的订单,那么就会出现一致性以阻止您执行此操作。
两者都是关于将数据库保持在可工作状态,因此它们的相似性。前一个示例将确保银行不会赔钱(或从您那里偷钱),后一个示例将确保您的应用程序不会对您一无所知的产品订单感到惊讶。
原子性:
在原子事务中,一系列数据库操作要么全部发生,要么什么都不发生。原子性保证可防止仅对数据库进行部分更新,这可能会导致比直接拒绝整个系列更大的问题。
一致性:
在数据库系统中,一致事务是在其执行期间不违反任何完整性约束的事务。如果事务使数据库处于非法状态,则将其中止并报告错误
如果事务成功完成,支持原子性但不支持一致性的数据库将允许使数据库处于不一致状态(即违反引用或其他完整性检查)的事务。例如,如果执行此操作的事务成功完成,您可以将字符串添加到 int 列。
相反,支持一致性但不支持原子性的数据库将允许部分事务完成,只要该事务的影响没有破坏任何完整性检查(例如,外键必须与现有身份匹配)。例如,您可以尝试添加一个包含 string 和 int 值的新行,即使插入在丢失一半数据的过程中失败,只要丢失的数据都不是必需的列且没有数据,则允许该行被插入到键入错误的列中。
话虽如此,一致性依赖于原子性来逆转不一致的事务。
原子性和一致性之间确实存在很强的关系,但它们并不相同:
DBMS 可以(理论上)支持一致性而不是原子性:例如,考虑一个包含 SQL 操作 O1、O2 和 O3 的事务。现在,假设在 O1 和 O2 之后 DB 已经处于一致状态。然后 DBMS 可以在没有 O3 的情况下在 O1 和 O2 之后停止事务,并且仍然保持一致性。显然,这样的 DBMS 不支持原子性(因为 O3 不是由 O1 执行的,而 O2 是)。
DBMS 可以(理论上)支持原子性而不是一致性:这可能发生在多用户场景中,原子性仅确保事务的所有操作都将执行(或不执行),但不能保证一个事务的操作与另一个事务同时完成的事务可能不会以不一致的状态结束。
但是,我确实相信(但尚未正式证明)是,如果您的 DMBS 保证原子性和隔离性,那么它也必须保证一致性。
我对 ACID 上下文中的一致性有不同的理解:
在事务中,如果检索到给定的数据项并稍后在同一事务中再次检索,则看不到任何更改。也就是说,事务在整个事务中被赋予数据库的一致状态。唯一可以更改对事务可见的数据的更新是由事务本身完成的更新。
在我看来,这无异于可序列化。
在阅读原子性和一致性时,我也感到困惑。假设有场景在帐户表中批量插入 1000 条记录。
批处理的原子性是如果插入了所有 1000 条记录,或者如果出现错误则不插入任何记录。
如果在帐户记录级别,将违反批次的一致性,我们已经放置了即使数据类型不匹配也使插入成功的逻辑,相关记录被插入到外键表中,然后在成功的帐户记录后删除更新。
希望这个例子能消除混乱。