Skip to content

Added optimistic concurrency with ETags to CosmosDB data access

Latest

Choose a tag to compare

@exiton3 exiton3 released this 20 Oct 06:11

Written for: developers using the AppFactory NuGet packages who read the GitHub release page.

This is a shorter version of the release notes from my earlier message:

## AppFactory Framework v10.9.0

### 🔒 CosmosDB: optimistic concurrency with ETags

Opt in per model to detect lost updates. Models without the setting behave as before.

```csharp
config.ContainerName("accounts")
      .Id(a => a.Id)
      .PartitionKey(a => a.Id)
      .ConcurrencyToken(a => a.ConcurrencyToken);   // string property, private setter is fine
  • Reads put the document's _etag into the property. It's never stored as data.
  • Update and Upsert throw ConcurrencyConflictException (AppFactory.Framework.Domain.Repositories) if the document changed since it was loaded.
  • After a successful Add, Update or Upsert, the token is refreshed, so the same instance can be updated again.

⚠️ Breaking change

  • ICosmosDbClient write methods now return CosmosDbClientResponse (IsSuccess, StatusCode, ETag, RequestCharge) instead of bool. Repository methods still return bool.
  • New member ConcurrencyToken(...) on IModelConfigOptions<TModel>. This only affects custom implementations of that interface.

✅ Tested against the Cosmos DB emulator

New integration tests run the CosmosDB features against the Cosmos DB emulator (Testcontainers).

Known issue

Ids from IdPrefix (for example USER#123) contain #, which Cosmos DB doesn't allow in id. GetById, Update and Delete return 404 for them. A fix is planned for a later release.

Full details: CHANGELOG.md