fix: let EF own the Postgres bootstrap transaction (EF Core 10)

EF Core 10 runs EnsureCreated through the migration executor, which begins
its own transaction unless EF already has one. The bootstrap held the
advisory lock in a transaction begun on the raw connection, invisible to
EF, so a fresh Postgres database failed at startup with "A transaction is
already in progress". Begin it through db.Database and take the lock with
ExecuteSqlRaw so EnsureCreated runs inside it.
This commit is contained in:
Alexa
2026-10-25 12:32:09 +02:00
parent cf7a021898
commit 9076fb9fae
+8 -7
View File
@@ -82,13 +82,14 @@ public static class DatabaseBootstrap
await Task.Delay(delay); await Task.Delay(delay);
} }
} }
await using var tx = await conn.BeginTransactionAsync(); // Begin the transaction through EF, not on the raw connection:
await using (var lockCmd = conn.CreateCommand()) // since EF Core 10, EnsureCreated runs its commands through the
{ // migration executor, which starts its own transaction unless EF
lockCmd.Transaction = tx; // already has one, and fails on a fresh database with "A
lockCmd.CommandText = "SELECT pg_advisory_xact_lock(1146246987);"; // transaction is already in progress" when the open one is
await lockCmd.ExecuteNonQueryAsync(); // invisible to it.
} await using var tx = await db.Database.BeginTransactionAsync();
await db.Database.ExecuteSqlRawAsync("SELECT pg_advisory_xact_lock(1146246987);");
db.Database.EnsureCreated(); db.Database.EnsureCreated();
await tx.CommitAsync(); await tx.CommitAsync();