BASE 风格数据库中的乐观锁

问题描述 投票:0回答:1

BASE 风格的数据库是软状态和最终一致的。我知道不同的数据库管理系统各不相同,它们的配置也有很大的差异。但让我们想象一下:

假设我有一个包含 2 个节点的 NoSQL 集群。最终是一致的。当我写入 Node1 时,一段时间后它会复制到 Node2。让我通过比较版本来实现乐观锁定机制。因此,当我尝试写入 Node1 时,如果我的版本落后于数据库中的版本,写入操作将不会成功。但是,当有两个线程(或进程)尝试更新同一行时,可能会发生类似的情况:

  1. thread1从Node1读取version=0的数据
  2. thread2从Node2读取version=0的数据
  3. thread1 更新 Node1 上 version=1 的数据
  4. thread2 尝试在 Node2 上更新 version=1 的数据,并且可能会成功,因为写操作可能尚未被复制。

我错过了什么吗?一些 BASE 风格的数据库系统如何解决这个问题?你能给我一些关于哪个数据库系统如何解决这个问题的可靠例子吗?

nosql couchbase distributed-computing eventual-consistency
1个回答
0
投票

我不确定这是解决此类问题的最佳论坛,因为它可能涉及讨论和来回。所以你可能想看看 Couchbase Discord

但是,我可以告诉你,对于 Couchbase(它可能满足你所描述的“BASE”标准,这是一个完全不同的对话),实现锁定的方法称为“Compare-and-Swap” ”(又名 CAS)。 来自文档

CAS,即比较和交换,是乐观锁定的一种形式。每一个 Couchbase 中的文档有一个 CAS 值,并且它每次都会发生变化 突变。当您获得文档时,您还会获得该文档的 CAS,并且 然后当需要编写文档时,您将相同的 CAS 发回。 如果另一个线程或程序修改了该文档 同时,Couchbase Server 可以检测到您提供了 现在已过时的 CAS,并返回错误。这提供了廉价、安全 并发。

文档中有关于如何在 SDK 级别工作的更多详细信息(例如,Java SDK 并发文档突变文档)。

作为数据库的最终用户,您需要担心的就是保留 CAS 值,因为它是乐观锁(和悲观锁,这也是 Couchbase 中的一个选项)的关键。比较乐观锁定的 CAS 值通常需要重试循环,以防文档出现争用。 (如果经常发生严重争用,请考虑使用悲观锁)。

如果您想更深入地了解实际的 CAS 实现(即,我猜您正在编写自己的数据库),我会再次指出 Couchbase Discord,因为核心工程师经常在那里闲逛。

© www.soinside.com 2019 - 2024. All rights reserved.