{"record":{"id":"808a87924c700d30","repo":"dotnet/efcore","slug":"user-transaction-is-not-supported-with-a-transacti","errorCode":null,"errorMessage":"User transaction is not supported with a TransactionSuppressed migrations or a retrying execution strategy.","messagePattern":"User transaction is not supported with a TransactionSuppressed migrations or a retrying execution strategy\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs","lineNumber":52,"sourceCode":"\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public virtual int ExecuteNonQuery(\n        IReadOnlyList<MigrationCommand> migrationCommands,\n        IRelationalConnection connection,\n        MigrationExecutionState executionState,\n        bool commitTransaction,\n        IsolationLevel? isolationLevel = null)\n    {\n        var inUserTransaction = connection.CurrentTransaction is not null && executionState.Transaction == null;\n        if (inUserTransaction\n            && (migrationCommands.Any(x => x.TransactionSuppressed) || executionStrategy.RetriesOnFailure))\n        {\n            throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction);\n        }\n\n        using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled);\n\n        return executionStrategy.Execute(\n            (migrationCommands, connection, inUserTransaction, executionState, commitTransaction, isolationLevel),\n            static (_, s) => Execute(\n                s.migrationCommands,\n                s.connection,\n                s.executionState,\n                beginTransaction: !s.inUserTransaction,\n                commitTransaction: !s.inUserTransaction && s.commitTransaction,\n                s.isolationLevel),\n            verifySucceeded: null);\n    }\n\n    private static int Execute(\n        IReadOnlyList<MigrationCommand> migrationCommands,","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs#L34-L70","documentation":"Thrown by the synchronous MigrationCommandExecutor.ExecuteNonQuery when there is an ambient user transaction on the connection AND either a migration command is marked `TransactionSuppressed` or the configured execution strategy retries on failure. Retrying or transaction-suppressed migrations cannot be coordinated with a caller-managed transaction.","triggerScenarios":"Calling `migrator.Migrate(...)` / `MigrateAsync` (or raw `IMigrationCommandExecutor.ExecuteNonQuery`) while you have already begun a transaction on the same `IRelationalConnection`, combined with a retrying execution strategy (e.g. SqlServer `EnableRetryOnFailure`) or a migration whose builder used `SuppressTransaction()`.","commonSituations":"Wrapping `Database.Migrate()` inside your own `Database.BeginTransaction()`; using `EnableRetryOnFailure` together with explicit transactions; custom hosting code that opens a transaction before seeding/migrating.","solutions":["Do not open your own transaction around `Migrate`; let EF own the migration transaction.","If you need a retrying strategy, remove the manual `BeginTransaction` call before migrating.","If a migration must run outside a transaction, ensure you are NOT also in a user transaction (call `Migrate` before `BeginTransaction`).","Separate migration application from your business-logic transaction entirely."],"exampleFix":"// before\nusing var tx = db.Database.BeginTransaction();\ndb.Database.Migrate();\n// after\ndb.Database.Migrate();\nusing var tx = db.Database.BeginTransaction();","handlingStrategy":"validation","validationCode":"// Never migrate inside a user transaction; verify before calling sync Migrate.\nif (db.Database.CurrentTransaction is not null)\n    throw new InvalidOperationException(\"Close/commit the ambient transaction before calling Migrate.\");\ndb.Database.Migrate();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call `Migrate` before `BeginTransaction`.","Do not enable `EnableRetryOnFailure` on the DbContext used for migrations inside a manual transaction.","Keep migration and business-work transactions on separate connection scopes."],"tags":["efcore","migrations","transactions","execution-strategy","relational"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}