EFCore.BulkExtensions icon indicating copy to clipboard operation
EFCore.BulkExtensions copied to clipboard

BulkSaveChanges throws An ambient transaction has been detected. The ambient transaction needs to be completed before beginning a transaction on this connection.'

Open SpaceOgre opened this issue 11 months ago • 2 comments

I changed from SaveChanges to BulkSaveChanges for one of our methods that does lots of inserts, it works fine when running the code in production but not during our integration tests since we wrap those in a TransactionScope. We get this error:

System.InvalidOperationException: An ambient transaction has been detected. The ambient transaction needs to be completed before starting a new transaction on this connection.
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.EnsureNoAmbientOrEnlistedTransactions()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.EnsureNoTransactions()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransaction(IsolationLevel isolationLevel)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.BeginTransaction()
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.BeginTransaction()
   at EFCore.BulkExtensions.DbContextBulkTransactionSaveChanges.SaveChangesAsync(DbContext context, BulkConfig bulkConfig, Action`1 progress, Boolean isAsync, CancellationToken cancellationToken)
   at EFCore.BulkExtensions.DbContextBulkTransactionSaveChanges.SaveChangesAsync(DbContext context, BulkConfig bulkConfig, Action`1 progress, Boolean isAsync, CancellationToken cancellationToken)
   at EFCore.BulkExtensions.DbContextBulkTransactionSaveChanges.SaveChangesAsync(DbContext context, BulkConfig bulkConfig, Action`1 progress, CancellationToken cancellationToken)
   at EFCore.BulkExtensions.DbContextBulkTransaction.ExecuteAsync[T](DbContext context, Type type, IEnumerable`1 entities, OperationType operationType, BulkConfig bulkConfig, Action`1 progress, CancellationToken cancellationToken)
   at GR.Elevinformation.Library.Features.Elinfiler.PostElinfilHandler.HandleAsync(PostElinfilRequest request, CancellationToken ct) in C:\Users\Nordstrom\source\GR\Elevinformation.API\source\GR.Elevinformation.Library\Features\Elinfiler\PostElinfilHandler.cs:line 43
   at GR.Elevinformation.API.Features.Elinfiler.PostElinfilEndpoint.HandleAsync(PostElinfilRequest req, CancellationToken ct) in C:\Users\Nordstrom\source\GR\Elevinformation.API\source\GR.Elevinformation.API\Features\Elinfiler\PostElinfilEndpoint.cs:line 29
   at FastEndpoints.Endpoint`2.ExecAsync(CancellationToken ct)
   at FastEndpoints.Endpoint`2.ExecAsync(CancellationToken ct)
   at NSwag.AspNetCore.Middlewares.SwaggerUiIndexMiddleware.Invoke(HttpContext context)
   at NSwag.AspNetCore.Middlewares.RedirectToIndexMiddleware.Invoke(HttpContext context)
   at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)

This seems like it is the same problem as issue: #598

The problem is at this line: https://github.com/borisdj/EFCore.BulkExtensions/blob/7feed457ecb1dbb5e5df72d08f7708aea0e90854/EFCore.BulkExtensions/DbContextBulkTransactionSaveChanges.cs#L103

context.Database.CurrentTransaction does not check Transactions from other places than those created via EF.

SpaceOgre avatar Mar 04 '24 07:03 SpaceOgre

I've been getting the same issue DbContextBulkTransactionSaveChanges too. I've submitted a pull request with my proposed fix for this.

filmstarr avatar Mar 04 '24 14:03 filmstarr

PR merged, thx for contrib. Will be released with next nuget.

borisdj avatar Mar 04 '24 16:03 borisdj