如何在使用 couchbase 子文档 api 执行更新时获取 CAS 值?

Posted

技术标签:

【中文标题】如何在使用 couchbase 子文档 api 执行更新时获取 CAS 值?【英文标题】:How to get CAS value while performing an update using couchbase subdocument api? 【发布时间】:2019-12-06 16:36:04 【问题描述】:

我想对文档进行更新。我正在使用 couchbase subdocument api 来更新文档。

在执行更新时,我手头只有文档 ID。但是,要获得当前的 Cas 值,我必须执行 get to the couchbase。

我的更新如下:

PrimaryBucket.mutateIn(document_id).upsert("path1","updatevalue1").upsert("path2","updatevalue2")

为了处理乐观锁定,我想使用"mutateIn(id).withCas(<currentcasvalue>)"

在执行更新时,我手头只有文档 ID。但是,要获得当前的 Cas 值,我必须执行 get to the couchbase。 有没有办法避免获取整个文档以便只获取 cas 值来执行更新。

这是正确的方法吗?

【问题讨论】:

这听起来像X/Y problem。为什么要在这种情况下使用乐观锁定?如果您所拥有的只是文档 ID,并且您对文档的当前状态一无所知,那么进行比较和交换会产生预期的效果并不明显。 【参考方案1】:

是的,有办法。您可以进行子文档查找以从文档中检索单个小路径,结果包括 CAS:

long cas = PrimaryBucket.lookupIn(document_id).get("path1").execute().cas();

PrimaryBucket.mutateIn(document_id).upsert("path1","updatevalue1").upsert("path2","updatevalue2").withCas(cas).execute();

如果您没有保证存在的路径,您可以使用 $document 虚拟 xattr 字段之一,如下所示:

long cas = PrimaryBucket.lookupIn(document_id).get("$document.exptime", new SubdocOptionsBuilder().xattr(true)).execute().cas();

【讨论】:

虽然您确实可以通过这种方式获取 CAS 值,但请注意 Couchbase 在进行更新时不使用提供的 CAS 值进行并发检查:Please note that this method will not use the Document.cas() for optimistic concurrency checks. If this behavior is needed, the replace(Document) method needs to be used. (docs.couchbase.com/sdk-api/couchbase-java-client-2.5.6/com/… ) @mnicky 用于 upsert 操作,它确实不支持 CAS。但是 OP 正在执行 mutateIn() 子文档操作,确实如此。

以上是关于如何在使用 couchbase 子文档 api 执行更新时获取 CAS 值?的主要内容,如果未能解决你的问题,请参考以下文章

Couchbase:查找二进制文档的索引

是否可以将Spring Data Couchbase映射到外部文档(来自依赖)?

Couchbase 使用键获取给定日期范围的文档

我如何从 pyspark 访问 couchbase

如何在Marklogic或Couchbase中进行xslt类型转换?

删除所有 Couchbase 数据/文档 ios(或删除所有 ios 数据?)