Iâm not the authority on transactions, and some of my assertions may not be completely accurate, but -
Going back to your original post -
âPS: We are using optimistic lock for updating documents.â
Thatâs usually sufficient for single document updates. If there is no additional requirements - then maybe you donât need transactions.
It would help to see the actual code because Iâm having difficulty understanding the description.
" 4. call the transaction.run method to execute the anonymous function (inside this, we only update the document. There is no document fetch operation.)"
This sounds like it is doing a non-tranactional update. ctx.replace takes a TransactionGetResult which comes from ctx.get. Since you havenât called any get in the transaction you wouldnât have a TransactionGetResult to pass to ctx.replace - are you using the non-tranactional collection.replace()? That executes independently of the transaction (It could still give CasMismatch, but itâs not from the transaction)
" 5. commit the transaction / in case of an exception roll it back. (this is done inside the anonymous function)"
transaction.run will call commit and rollback; the application code should not be calling them (Iâm not even sure that it can). If you are calling collection.replace() instead of ctx.replace, then there are no changes in the transaction; commit (called explicitly or by transaction.run) will be a no-op and always succeed. An exception (such as CasMismatch from collection.replace) thrown in the anonymous method can (maybe?) cause transaction.run to re-execute the anonymous method - but it would continue to fail with CasMismatch as the old cas (which was obtained from the collection.get from outside the transaction.run) will never match.
âWe are observing that inspite of sending the CAS value during the update operation, the document is being overwritten by a parallel update operationâ
Letâs see⌠ok.
âWe do have a retry wherein once we receive a CasMismatchException from couchbase, we fetch the document once again and then again restart the transaction.â
Yes. So when the CasMismatch is thrown - itâs preventing a previous modification from being overwritten. But when you retry - you re-fetch the (now modified) document, and reapply the changes (or use the complete, modified document that failed previously with CasMismatch) you overwrite the changes that gave the CasMismatch.
In case it didnât get mentioned - if you are updating a document in a transaction in one place, then every place that document is updated should be in a transaction. The transaction mechanism only works when every update uses it.
And using collection.replace (or anything method that is not ctx.*) inside a transaction.run is not transactional. While nothing is preventing calls to collection.get etc inside transaction.run, its probably not the call you should be making. ctx.get etc are most likely the correct calls.
To better see what is going on, print out the document and cas after every get operation and before every replace operation.