3

I want to perform update on documents. I am using couchbase subdocument api to update the documents.

While performing the update,I only have the document id at hand. However to get the current Cas value I have to perform a get to the couchbase.

My update looks like:

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

To handle optimistic locking, i want to use "mutateIn(id).withCas(<currentcasvalue>)"

While performing the update,I only have the document id at hand. However to get the current Cas value I have to perform a get to the couchbase. Is there a way to avoid fetching the whole document in order to only get the cas value to perform the update.

Is this the correct approach?

Dvyn Resh
  • 980
  • 1
  • 6
  • 14
  • This sounds like an [X/Y problem](https://meta.stackexchange.com/a/66378). Why do you want to use optimistic locking in this case? If all you have the is the document ID and you don't know anything about the current state of the document, then it's not obvious that doing a compare-and-swap will have the desired effect. – dnault Jul 29 '19 at 17:59

1 Answers1

1

Yes, there is a way. You can do a Sub-Document lookup to retrieve a single small path from the document, and the result includes the CAS:

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

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

If you don't have a path that's guaranteed to exist you can use one of the $document virtual xattr fields like so:

long cas = PrimaryBucket.lookupIn(document_id).get("$document.exptime", new SubdocOptionsBuilder().xattr(true)).execute().cas();
Graham Pople
  • 416
  • 4
  • 8
  • while it's true that you can obtain CAS value this way, be wary of a fact that Couchbase doesn't use the provided CAS value for concurrency check when doing the update: `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.` (https://docs.couchbase.com/sdk-api/couchbase-java-client-2.5.6/com/couchbase/client/java/AsyncBucket.html#upsert-D- ) – mnicky Jan 09 '20 at 14:55
  • 1
    @mnicky that's for an upsert operation, which indeed does not support CAS. But the OP is doing a mutateIn() Sub-Document operation, which does. – Graham Pople Jan 10 '20 at 15:35