Skip to content

fix: Reserve idempotency keys atomically in TryStoreAsync in all SQL/EF providers #907

Description

@samtrion

User Story

As a developer running multiple Pulse instances with a SQL or Entity Framework idempotency store, I want the key reservation to be atomic, so that a command submitted concurrently with the same idempotency key runs its handler exactly once.


Problem

#816 adds IIdempotencyKeyRepository.TryStoreAsync and makes the Redis provider reserve keys atomically. The SQL Server, PostgreSQL, MySQL, SQLite and Entity Framework providers implement TryStoreAsync by composing ExistsAsync and StoreAsync, and their XML remarks say so ("not atomic").

Failure scenario: instances A and B receive the same command at the same time.

  1. A and B both call ExistsAsync and get false.
  2. Both call StoreAsync. The duplicate insert is swallowed (or updates the row), so neither call fails.
  3. Both TryReserveAsync calls return true, and the handler runs twice.

The shared integration test base (tests/NetEvolve.Pulse.Tests.Integration/Idempotency/IdempotencyTestsBase.cs) already contains the concurrency tests. They are skipped for these providers because SupportsAtomicReservation is false.


Requirements

Related: #816, #814.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugIndicates an issue or flaw that needs to be fixed.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions