Repository navigation
fix: leave a write of a document the same save inserts unguarded by the concurrency token - #92
Open
kerem-acer wants to merge 1 commit into
Open
kerem-acer wants to merge 1 commit into
kerem-acer wants to merge 1 commit into
Conversation
…he concurrency token Adding a document and then replacing, updating or deleting it (with soft delete, an update) in the same save failed with ConcurrencyException. The token guarded the write and incremented the token on the document before the insert wrote it, so the insert stored the incremented token and the write, checked against the one before, matched nothing; the whole save rolled back. InsurUp core's policy import does exactly this for a policy created and endorsed in one file batch, and works around it with Without(ConcurrencyTokenFeature.Key). Such a write is now neither checked nor incremented: the insert writes the document as it is, nothing can have changed it in between, and it's stored with the token it was added with, which the next save checks against. A different instance with the same key is guarded as before. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adding a document and then replacing, updating or deleting it in the same save fails with
ConcurrencyExceptionunder the concurrency token. A delete counts here when soft delete turns it into an update. The whole save rolls back. InsurUp core hits this in its policy import. A policy created and endorsed in one file batch isAdded and thenReplaced before the batch saves, and core works around it withWithout(ConcurrencyTokenFeature.Key)(core#1790).The cause:
ConcurrencyTokenInterceptor.SavingAsyncguards the replace and increments the token on the document before any write runs. The insert then writes the document with the incremented token. The replace, checked against the token as it was read, matches nothing.What it does
SavingAsyncfirst collects the documents the save inserts, by reference, but only when the save inserts any. A replace, update or delete made with one of those documents is neither checked nor incremented. The insert writes the document as it is, and nothing can have changed it in between. It's stored with the token it was added with, and the next save checks against that. A different instance with the same key is still guarded as before.docs/features.mdsays this under "Concurrency token".Tests
ConcurrencyTokenTests.SameSave.cs(integration):Replace_DocumentTheSameSaveInserts_WritesItWithTheTokenAsAdded: the latest state is stored atver: 0.Update_DocumentTheSameSaveInserts_AppliesTheUpdateAndLeavesTheToken: the update applies and the token stays 0.Delete_SoftDeletableDocumentTheSameSaveInserts_MarksItWithTheTokenAsAdded: the document is stored marked, atVersion: 0.Replace_AfterTheSaveThatInsertedAndReplacedTheDocument_IsCheckedAgainstTheStoredToken: the next checked replace succeeds and stores 1.Delete_DocumentTheSameSaveInserts_DeletesIt: a hard delete, covered for completeness.The first four fail on
mainwithConcurrencyException; the hard delete passes either way, because a delete doesn't increment. All of them pass here. ConcurrencyTokenTests (31) pass on net10.0 and net11.0, and ChangeTrackingTests (74) and SoftDeleteTests (11) on net10.0. Formatting and the Release/warnaserrorrebuild are clean.🤖 Generated with Claude Code