This code:
public async Task<IActionResult> UpdateAsync() // no relevant for bug
{
var texts = new string[] { "Text1", "Text2" };
var dbContext = _serviceProvider.GetRequiredService<MyDbContext>();
var txn = dbContext.Database.BeginTransaction(); // no relevant for bug
texts.ToList().ForEach(async textValue =>
{
var entity = new TextTable() { Text = textValue };
_ = await dbContext.Set<TextTable>().AddAsync(entity);
await dbContext.SaveChangesAsync(); // bug occure on second call
});
txn.Rollback(); // no relevant for bug
return BadRequest(); // no relevant for bug
}
raises an exception and causes the application to crash hard.
Version 8.21.150 does not cause this problem.
Exception:
System.InvalidOperationException
HResult=0x80131509
Message=A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__111.MoveNext()
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__115.MoveNext()
at Oracle.EntityFrameworkCore.Storage.Internal.OracleExecutionStrategy.<ExecuteAsync>d__8`2.MoveNext()
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__63.MoveNext()
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__63.MoveNext()
at Api.Controllers.TestController.<>c__DisplayClass6_0.<<UpdateAsync>b__0>d.MoveNext() in C:\TestController.cs:line 20
Notes:
- dotnet 8, EF 8.0.8
- MyDbContext is generated from database.
- PrimaryKey in TextTable is column ID - NUMBER(12). ID is automatic generated by trigger and sequence
modelBuilder.Entity<TextTable>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK_TEXT_TABLE");
entity.ToTable("TEXT_TABLE");
entity.Property(e => e.Id)
.HasPrecision(12)
.HasColumnName("ID");
entity.Property(e => e.Text)
.HasMaxLength(20)
.IsUnicode(false)
.HasColumnName("TEXT");
...
...
}