CASmismatch exception when replacing documents over same connection

CB server v7.0.5
java sdk v3.4.3/3.6.0

Whenever I am doing replaceWithCas for more than 1 document over single connection, it always fails with CasMismatchException

CasMismatchException: Document has been concurrently modified on the server {"completed":true,"coreId":"0x2929a68a00000001","idempotent":false,"lastChannelId":"2929A68A00000001/00000000E6F0546E","lastDispatchedFrom":"a.b.c.d","lastDispatchedTo":"x.x.x.x:11210","requestId":34,"requestType":"ReplaceRequest","retried":0,"serverDuration":38,"service":{"bucket":"storage-test","collection":"_default","documentId":"5ff7ff4c-fbe9-437e-8bcf-92d198adbe33","errorCode":{"description":"key already exists, or CAS mismatch","name":"KEY_EEXISTS"},"opaque":"0x44","scope":"_default","type":"kv","vbucket":685},"status":"EXISTS","timeoutMs":2500,"timings":{"dispatchMicros":19828,"encodingMicros":38580,"totalDispatchMicros":19828,"totalServerMicros":0,"totalMicros":20927,"serverMicros":0}}

I tried this both using CompletableFutures as well as serial insert of documents. Just before invoking replace, I print the CAS which matches the one in the Get call. Also, I read CAS using N1QL in web console, it gives wrong CAS and ast 2 digits are 0s for all documents. So it looks like the rounding bug is also still not resolved.

Here is the code I use to do replaceWithCas

 public Map<String, MutationResult> replaceWithCas(@NotNull ArrayList<CoreIo.Document> replaceDocInput,
                                                                    Predicate<GetResult> predicate) throws RetryableException {

       
        for (CoreIo.Document doc : replaceDocInput) {
            Collection collection =
                    cbBuckets.get(doc.getBucketName()).getBucket().defaultCollection();
            try {
                logger.debug("replace_with_cas:" + doc.getKey());
                GetResult result = collection.get(doc.getKey());
                System.out.println("to replace get doc:"+ result.contentAsObject().toString()+","+ result.cas());
                
                    System.out.println("to replace modified doc:"+ result.contentAsObject().toString()+","+ result.cas());
                    MutationResult res = collection.replace(
                            doc.getKey(),
                            doc.getData(),
                            ReplaceOptions.replaceOptions().cas(doc.getCas())
                    );
                    logger.debug("replace_with_cas:success:" + doc.getKey());
                logger.debug("replace_with_cas:success:" + res.cas());
                  
            } catch (DocumentNotFoundException ex) {
                logger.error("replace_with_cas:document not existent:" + doc.getKey());
             
            } catch (Exception ex) {
                logger.error("replace_with_cas:exception:" + doc.getKey() + ":" + ex.getMessage());
                ex.printStackTrace();
       
            }

        }
                Map<String, MutationResult> mutationResultMap = new HashMap<>();

        logger.debug("replace_with_cas:done");
        return mutationResultMap;
    }

I also introduced retry. In all retries, the CAS value from get() call is always same, but it still gives same exception.

14-03-2024 15:43:11.879 [pool-2-thread-2] DEBUG com.connector.couchbase.Couchbase - attempt: 0 replace_with_cas:07760cb0-ff8d-46d8-b454-84ebbafd22cb
to replace get doc:{"name":{"fname":"abcd","classesPassed":[1],"sname":"pqrs"},"age":1,"id":"07760cb0-ff8d-46d8-b454-84ebbafd22cb"},1710411190662266880
14-03-2024 15:43:11.965 [pool-2-thread-2] ERROR com.connector.couchbase.Couchbase - replace_with_cas:exception:07760cb0-ff8d-46d8-b454-84ebbafd22cb:Document has been concurrently modified on the server {"completed":true,"coreId":"0x8c819c000000001","idempotent":false,"lastChannelId":"08C819C000000001/00000000B32BAD8F","lastDispatchedFrom":"a.b.c.d","lastDispatchedTo":"x.y.z:11210","requestId":35,"requestType":"ReplaceRequest","retried":0,"serverDuration":38,"service":{"bucket":"storage-test","collection":"_default","documentId":"07760cb0-ff8d-46d8-b454-84ebbafd22cb","errorCode":{"description":"key already exists, or CAS mismatch","name":"KEY_EEXISTS"},"opaque":"0x45","scope":"_default","type":"kv","vbucket":368},"status":"EXISTS","timeoutMs":2500,"timings":{"dispatchMicros":20602,"encodingMicros":30881,"totalDispatchMicros":20602,"totalServerMicros":0,"totalMicros":24846,"serverMicros":0}}

14-03-2024 15:43:11.966 [pool-2-thread-2] DEBUG com.connector.couchbase.Couchbase - attempt: 1 replace_with_cas:07760cb0-ff8d-46d8-b454-84ebbafd22cb
to replace get doc:{"name":{"fname":"abcd","classesPassed":[1],"sname":"pqrs"},"age":1,"id":"07760cb0-ff8d-46d8-b454-84ebbafd22cb"},1710411190662266880
14-03-2024 15:43:11.989 [pool-2-thread-2] DEBUG com.connector.couchbase.CouchbaseCluster - replace_with_cas:not business event
to replace modified doc:{"name":{"fname":"abcd","classesPassed":[1],"sname":"pqrs"},"age":1,"id":"07760cb0-ff8d-46d8-b454-84ebbafd22cb"},1710411190662266880
14-03-2024 15:43:12.010 [pool-2-thread-2] ERROR com.connector.couchbase.Couchbase - replace_with_cas:exception:07760cb0-ff8d-46d8-b454-84ebbafd22cb:Document has been concurrently modified on the server {"completed":true,"coreId":"0x8c819c000000001","idempotent":false,"lastChannelId":"08C819C000000001/00000000B32BAD8F","lastDispatchedFrom":"a.b.c.d","lastDispatchedTo":"x.y.z:11210","requestId":37,"requestType":"ReplaceRequest","retried":0,"serverDuration":43,"service":{"bucket":"storage-test","collection":"_default","documentId":"07760cb0-ff8d-46d8-b454-84ebbafd22cb","errorCode":{"description":"key already exists, or CAS mismatch","name":"KEY_EEXISTS"},"opaque":"0x47","scope":"_default","type":"kv","vbucket":368},"status":"EXISTS","timeoutMs":2500,"timings":{"dispatchMicros":18987,"encodingMicros":198,"totalDispatchMicros":18987,"totalServerMicros":0,"totalMicros":19853,"serverMicros":0}}

1710411190662266880 is the cas value here

@Ankur-Shukl should you not be using result.cas() rather than doc.getCas() in your replace call?

1 Like