From 3b332a64762ae7665635847e89897e3bb1b72bd9 Mon Sep 17 00:00:00 2001 From: Alexa <53471801+Alexa-RR@users.noreply.github.com> Date: Sun, 25 Oct 2026 12:32:09 +0200 Subject: [PATCH] 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. --- DorkNet.Server/Startup/DatabaseBootstrap.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/DorkNet.Server/Startup/DatabaseBootstrap.cs b/DorkNet.Server/Startup/DatabaseBootstrap.cs index 485b5bc..bb5b946 100644 --- a/DorkNet.Server/Startup/DatabaseBootstrap.cs +++ b/DorkNet.Server/Startup/DatabaseBootstrap.cs @@ -82,13 +82,14 @@ public static class DatabaseBootstrap await Task.Delay(delay); } } - await using var tx = await conn.BeginTransactionAsync(); - await using (var lockCmd = conn.CreateCommand()) - { - lockCmd.Transaction = tx; - lockCmd.CommandText = "SELECT pg_advisory_xact_lock(1146246987);"; - await lockCmd.ExecuteNonQueryAsync(); - } + // Begin the transaction through EF, not on the raw connection: + // since EF Core 10, EnsureCreated runs its commands through the + // migration executor, which starts its own transaction unless EF + // already has one, and fails on a fresh database with "A + // transaction is already in progress" when the open one is + // invisible to it. + await using var tx = await db.Database.BeginTransactionAsync(); + await db.Database.ExecuteSqlRawAsync("SELECT pg_advisory_xact_lock(1146246987);"); db.Database.EnsureCreated(); await tx.CommitAsync();