Not seeing updated value after running @Query

I am using spring-data-couchbase 4.1.1 with sdk 3.0.6 on spring-boot-2.3.2. In my application code, I have an @Query annotated method that updates the status of a document from one state to another. It is a simple “Update set where meta().id=foo” type query with return type void of the annotated method. In my integration test (using couchbase container 6.5.1), sometimes ( 1 out 2 or more) this method doesn’t update the status and my assertion fails. I can clearly see in logs that the method ran without any exception. Does anyone have any idea why this might be occurring?

Strangely when I run that particular test separately from other tests. This error did never happen. Only when I run all the tests together, this happens. I am very much sure that all the tests are independent as I clean up all data after each test.

Also, other tests also use this annotated method but only 2 tests are consistently giving assertion errors.

I know this is way too abstract to think. I have also just started to debug my situation

Update: Now it is 3 tests that have shown this issue. In this test, An operation needs to happen only once before the state of the document is changed to COMPLETED. This operation should only run once. To test this I run multiple threads to execute that operation, once a thread is able to complete its job it marks the status as Completed and decreases a pending job counter. In the end, that job counter value should be 0 but it turned out -1 which means two threads were able to run the same operation. The first thread ran, completed the job, decremented the counter from 1 to 0 but the status didn’t change. Now, the second thread saw the status was still not completed and ran the operations again and decremented the counter to -1.

Earlier, I was on spring-data-couchbase 3.x and never saw such an issue. It is only after I have upgraded it to 4.x in the last 2 days that it started causing issue

Replaced the @Query annotation with a concrete implementation using couchbase sdk directly. Now using collection.mutateIn(). The issue disappeared completely. So, the problem is not with my tests at least. I am thinking does @Query fails silently and doesn’t propagate error? I remember there was a template configuration where one could set something like this. Even if it is failing, why is it failing so many times and only in such a situation?

I am hypothesizing that it is the case of failing to read your own write scenario. Just before updating the status, I save the document to the database. Maybe the index service is not updated when I run the n1ql and hence the update doesn’t happens. I want to test this hypothesis but can’t find where I can set this consistency level. In the earlier version, this configuration was present. I’ll try to find how to set this and let know.

There is also another n1ql query that is failing. It is a read query with no index scan. It is a simple select query based on some attributes. In this case also, I save the document fist and then do the read but I am not sure why this would be failing even if the case is like the above I have described. I should be able to read what I just wrote, especially one no index is involved

Hi Sahil,

Yes, if you want “ready your own write” semantics for a query, you need to use the @ScanConsistency annotation.

That said… whenever you know the document ID, it’s usually [always?] faster to read or update the document using the K/V API instead of N1QL. With the K/V API, you can always read your own writes (except in the rare event that you wrote to a node that failed before the write was propagated to a replica – see Durability for more info on mitigating that scenario).

Thanks,
David

Hi David, thanks for the reply.

I am almost certain now that the behavior I observed was because of inconsistency between the primary index and data service.

But can you give me some idea why it might have been failing for the second type of n1ql queries where no index is involved?

“There is also another n1ql query that is failing. It is a read query with no index scan. It is a simple select query based on some attributes. In this case, also, I save the document first and then do the read but I am not sure why this would be failing even if the case is like the above I have described. I should be able to read what I just wrote, especially one no index is involved”

This read query just returns empty data even though the document is saved. And since no index is involved it shall do a full scan of the bucket to get the doc that matches the filter.

Use scan _consistency.
or
As you know document key use SDK
OR
UPDATE bucket USE KEYS “document key” SET …
WHERE META().id = “foo” uses indexscan

If query did not have USE KEYS , N1QL uses index. Index is eventually consistent.