Skip to content

feat(flag): add optimistic concurrency token via xmin - #58

Merged
amodelandme merged 2 commits into
devfrom
feat/add-concurrency-token-to-domain-model
May 1, 2026
Merged

amodelandme merged 2 commits into
devfrom
feat/add-concurrency-token-to-domain-model

Conversation

@amodelandme

Copy link
Copy Markdown
Owner
  • Map Flag.Version (uint) to the Postgres xmin system column with IsRowVersion(). EF includes it in the WHERE clause on every UPDATE/DELETE, so conflicting writes raise
    DbUpdateConcurrencyException instead of silently last-write-winning.
  • Translate DbUpdateConcurrencyException at the repository edge into a new FlagConcurrencyException (HTTP 409), mirroring the existing 23505 → DuplicateFlagNameException pattern. Application and API
    layers stay free of EF Core types.
  • Integration test proves the token fires: two scopes load the same flag, scope A saves, scope B's save throws.

Why xmin over byte[] Version

byte[] Version + IsRowVersion() is the canonical EF Core row-version pattern but only works on SQL Server. On Npgsql it produces a bytea column the database never auto-updates — the concurrency check
becomes a silent no-op. uint Version lets the Npgsql provider map to xmin, which Postgres maintains on every row change for free. The generated migration emits no real DDL because xmin is a system column
already present on every Postgres row.

Follow-ups (not in this PR)

  • API-level test issuing concurrent PUT /api/flags/... requests and asserting a 409 ProblemDetails response.
  • Revisit if a detach/reattach code path is added (rename property to xmin to be safe).

Test plan

  • dotnet build Banderas.sln -p:TreatWarningsAsErrors=true — 0 warnings, 0 errors
  • dotnet test Banderas.sln --filter "FullyQualifiedName~FlagConcurrencyTokenTests" — passes
  • Full suite: dotnet test Banderas.sln
  • dotnet ef database update applies cleanly on a fresh Postgres
  • Manual: load a flag, mutate via two clients, confirm second receives 409

@amodelandme
amodelandme merged commit 454630c into dev May 1, 2026
5 checks passed
@amodelandme
amodelandme deleted the feat/add-concurrency-token-to-domain-model branch May 5, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant