Skip to content

fix: serialize InitializeDb across concurrent instances - #47

Merged
giammin merged 2 commits into
mainfrom
fix/20-concurrent-initializedb
Oct 22, 2026
Merged

giammin merged 2 commits into
mainfrom
fix/20-concurrent-initializedb

Conversation

@giammin

@giammin giammin commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Summary

InitializeDb() failed when several instances started at the same time: concurrent existence checks all passed and the later CREATE statements failed.

  • SQL Server: "There is already an object named ..." / "index ... already exists".
  • PostgreSQL: 23505 duplicate key value violates unique constraint "pg_class_relname_nsp_index".

The DDL now runs in a transaction that first takes a database-wide lock, so concurrent calls wait for each other:

  • SQL Server: sp_getapplock (exclusive, owned by the transaction); a negative result raises a clear error.
  • PostgreSQL: pg_advisory_xact_lock(hashtext(...)).

The lock name is a private constant shared by all tables in the database; initialization is short, so serializing different tables is harmless. A blocked call waits up to the command timeout (30 s by default).

Tests

New InitializeDb_ConcurrentCallsOnNewTable_AllSucceed per provider: 10 repositories call InitializeDb() together (released by a Barrier on dedicated threads) on a new table, 5 rounds. The connection pool is warmed first; with cold connections the calls are staggered and the race rarely shows.

  • Before the fix (20 iterations each): SQL Server failed 20/20, PostgreSQL failed at least 10/20.
  • After the fix: 40/40 pass; full suite 81/81.

Docs

README Configuration section notes that concurrent startup is safe.

Closes #20

Run the initialization DDL in a transaction that first takes a
database-wide lock (sp_getapplock on SQL Server, pg_advisory_xact_lock
on PostgreSQL), so instances starting at the same time wait for each
other instead of failing with "object already exists" or a unique
violation in the PostgreSQL system catalogs.

Add a concurrency test per provider (10 parallel calls on a new table,
5 rounds) and document the behavior in the README.

Closes #20
@giammin
giammin merged commit f207e22 into main Oct 22, 2026
1 check passed
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.

InitializeDb can fail when several nodes start at the same time

1 participant