A:简而言之,当定义ACID 主体,特别是一致性部分时,早在分布式数据成为关系数据库的概念之前。所以从这个角度来看,一致性是自动的,因为只有一个服务器在运行。一旦提交了事务,服务器立即与自身保持一致,关于该事务和与之相关的所有约束,没有其他服务器可以同步和提交。(请注意,这仅集中在ACID 主体中的一致性含义的一部分,以与 OP 关于分布式数据的问题的相关性。)
现在有许多符合 ACID 的关系数据库系统,旨在处理跨多个服务器的分布式数据。但是,让我们暂时以 Microsoft SQL Server 及其AlwaysOn 可用性组功能为例。此功能旨在通过将数据从主服务器同步到其他辅助服务器来实现高可用性/灾难恢复功能。它也符合 ACID,因为它可以配置为确保跨服务器的一致性(当设置为同步时模式)。关于它如何工作的一个非常基本的解释是,只有在事务从主服务器同步到所有辅助服务器后,它才会完全提交事务。这保证了所有服务器在任何时候的一致性,并允许它在分布式服务器环境中保持ACID 兼容。
直接回答您的问题:
A:简而言之,当定义ACID 主体,特别是一致性部分时,早在分布式数据成为关系数据库的概念之前。所以从这个角度来看,一致性是自动的,因为只有一个服务器在运行。一旦提交了事务,服务器立即与自身保持一致,关于该事务和与之相关的所有约束,没有其他服务器可以同步和提交。(请注意,这仅集中在ACID 主体中的一致性含义的一部分,以与 OP 关于分布式数据的问题的相关性。)
现在有许多符合 ACID 的关系数据库系统,旨在处理跨多个服务器的分布式数据。但是,让我们暂时以 Microsoft SQL Server 及其AlwaysOn 可用性组功能为例。此功能旨在通过将数据从主服务器同步到其他辅助服务器来实现高可用性/灾难恢复功能。它也符合 ACID,因为它可以配置为确保跨服务器的一致性(当设置为同步时模式)。关于它如何工作的一个非常基本的解释是,只有在事务从主服务器同步到所有辅助服务器后,它才会完全提交事务。这保证了所有服务器在任何时候的一致性,并允许它在分布式服务器环境中保持ACID 兼容。
答:实际上并没有一种方法可以量化地回答这个问题,但一般来说,是的。参照完整性是使用关系数据库的要点之一。当有一个关系定义良好的模式,并定义了适当的约束(例如外键)时,关系数据库可以保证始终强制执行这些约束的规则,以确保它始终强制执行适当的引用完整性。这与一致性的定义以及关系数据库如何与ACID兼容有关。
我将尝试仅回答 1:
这取决于 DBMS 和 DB 拓扑的配置设置,但答案可以是:
是的,关系 DB 不是最终一致的,而是真正一致的。
例如,在 Postgres 中,有几个synchronous_commit设置允许不同级别的一致性。来自文章你应该在 PostgreSQL 中使用同步复制吗?:
基本上它说提交只有在写入副本(“奴隶”)后才可读。
Postgres 和所有其他允许类似行为的主要 DBMS 中也有“master-master”配置,具有多个写入节点(“master”)。
读取一致性取决于活动的事务隔离级别。在这里,您需要权衡一致性要求与性能和其他错误状态。
大多数应用程序都摆脱了相当“弱”的隔离保证,因为 JOIN 仍然不会返回不一致的数据。例如,
您通常会使用代理键插入值,例如
从技术上讲,这是两个事务,因此即使在最高隔离级别上它们也变得独立可见,但是如果您的查询要求
你仍然只会得到完整的套装。对于大多数应用程序来说,这已经足够了,并且避免更强隔离级别所需的额外应用程序逻辑(由于并发事务,事务可以看似随机地被拒绝)是可取的。
数据库将拒绝导致违反约束的事务,但允许事务中间的非法中间状态。例如,
如果存在这样的行,则会出错
one
;BEGIN
反向顺序的相同事务是可以的,就像用and将两个语句包装成一个事务一样COMMIT
。如果你喜欢危险的生活,你也可以给出一个ON DELETE CASCADE
规则,删除所有依赖的行。从数据库服务器的角度来看一致性:查询被发送到服务器,在那里进行处理,并返回结果集。网络延迟与一致性无关:两个不相互通信的客户端无法找出哪个客户端先发送了查询,因此服务器选择任意顺序。
如果两个客户端确实互相交谈,并且一个通知另一个它刚刚插入数据并从服务器获得了确认,那么第二个客户端将能够在其查询中看到数据。
复制的数据库仍将保留此属性,但更高的隔离级别会导致更严格的性能损失,因为确认事务需要所有节点确认没有其他活动事务与它发生冲突,并且获得这种共识需要时间。
在更高的隔离级别下,已经开始新事务的客户端
BEGIN
可以对数据库的冻结视图执行SELECT
查询,该视图不反映任何其他正在运行的事务,但任何读取的数据都将被锁定直到事务结束,使得并发写入失败。从应用程序程序员的角度来看,您通常会在 DBMS 中执行修改,而不是检索数据、修改数据并将其写回,例如
这很好地避免了与其他事务的一致性问题,即使在较低的隔离级别下,也可以让您摆脱锁定:两个这样
UPDATE
的查询可以从不同的客户端发送,并且 DBMS 可以在内部解决它们,并且不会因网络周转时间而延迟。约束不必是参考的:
balance
需要为正的约束将为每个事务验证,如果只能执行一个,则返回第二个错误(对于并发事务,哪个是“第二个”是任意的)。这些约束检查是您想要使用 RDBMS 的主要原因之一,但这仅限于可以表示为有限数量的表和适当索引之间的关系的数据结构,因此例如很难表达以允许高效查询的方式绘制图形或层次结构,这就是 NoSQL 的用武之地。