NpgsqlRetryingExecutionStrategy rejects user-initiated transactions: SaveChanges inside a BeginTransactionAsync block triggers OnFirstExecution which throws InvalidOperationException. Fix: CreateExecutionStrategy().ExecuteAsync wraps the entire tx block; mutable state (counters, contactByNorm, change tracker) reset at lambda top for idempotent retry. Logic extracted to RunLoopAsync local function shared by dry-run and execute paths. Regression test (Test 7): FakeRetryingStrategy with MaxRetryCount=1 reproduces the OnFirstExecution check in CI without a live Npgsql instance. 165/165 tests, ef has-pending=No, no schema change. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
21 KiB
21 KiB