如何在使用 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 值?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以将Spring Data Couchbase映射到外部文档(来自依赖)?