Optimistic Locking doesn't appear to be working any longer when using the repository "save" method to save an entity. This was previously working in the 1.4 release.
Steps to reproduce:
-Create a Document class with the @Version annotation
-Create a CrudRepository referencing the Document class
-Load an existing document via the repository "findOne" method in thread 1 (validated the cas is set in this document)
-In thread 2 update the same document
-In thread 1, save the document using the repository "save" method
A CASMismatchException is thrown
No exception is thrown and thread 1 overwrites the document thread 2 had saved
Note: this exact scenario was working in 1.4 release
Affects: 2.0 GA, 2.1 RC1 (Hopper)
DATACOUCH-224 Improve concurrent save/insert optimistic locking
("is depended on by")
The text was updated successfully, but these errors were encountered:
I've just found the same issue, tried last version with fix. But it seems that it does not handle case of concurrent writes of new document with the same key.
I have created pull request with failing test for this case: #109
I am not sure, but it looks like it is not quite correct behavior
@anastasiia thanks for checking this further. Turns out the OptimisticLocking check is only meaningful if the @Version annotated field bears a CAS that is non-zero.
So what you could do is do a first insert, get the associated version value and set that as the version of the ones that you construct in the threads. This should trigger the optimistic locking. I'll comment on the PR with some code to achieve that, since JIRA is not ideal for long(ish) code snippets ;)
Thanks for the quick reply!
I was hoping to use only CrudRepository interface for merging data, but it looks like I need more low level operations to do that. In previous version of spring-data-couchbase this case worked, but now not. :( I think, that this case should be handled appropriately by Repository without any other manipulations with neither CouchbaseOperation nor Bucket. Correct me if I am wrong. Thanks
I think it should work equally as well with the CrudRepository, just that you need a non-zero value for the @Version field (since this maps to the CAS in couchbase, and at the protocol level the CAS is not checked against if it is 0)
Jordan's scenario works as well: get the doc from the database (through the repository), which will populate it's @Version annotated field. Mutate that document and save, or reuse that document's version value and attempt multiple parallel saves