C
C#2y ago
Sparky

EF Core is throwing DbUpdateConcurrencyException, but only on the production database (MySQL)

I am trying to deploy a web application to a server, but I'm running into a weird issue. There is a schedules task in the app, that downloads some data from a different server, and inserts a large amount of rows into a database table. On my local development machine (Windows 11, MySQL 8.0.31) this works without any issues. But when I connect it to the production database (MySQL 8.0.30-0ubuntu0.20.04.2), this specific part of the application fails by throwing a DbUpdateConcurrencyException. Here's the simplified version of the code in question:
public async Task Execute(IJobExecutionContext context)
{
// databaseFactory is injected as a dependency (IDbContextFactory<AppDatabase>)
await using var database = await databaseFactory.CreateDbContextAsync();

int page = 0;
while(true)
{
List<WarehouseEntry> dbItems = warehouse.QueryPage(page, 1000); // Retrieves 1000 entries from somewhere
if(dbItems.Count == 0)
break;

database.ProductWarehouseCache.AddRange(dbItems.Select(p => new CachedWarehouseProduct {
Sku = p.Name,
Barcode = p.Barcode,
Stock = p.Stock,
Price = p.Price
}));

await database.SaveChangesAsync(); // <---- DbUpdateConcurrencyException is thrown here
page++;
}
}
public async Task Execute(IJobExecutionContext context)
{
// databaseFactory is injected as a dependency (IDbContextFactory<AppDatabase>)
await using var database = await databaseFactory.CreateDbContextAsync();

int page = 0;
while(true)
{
List<WarehouseEntry> dbItems = warehouse.QueryPage(page, 1000); // Retrieves 1000 entries from somewhere
if(dbItems.Count == 0)
break;

database.ProductWarehouseCache.AddRange(dbItems.Select(p => new CachedWarehouseProduct {
Sku = p.Name,
Barcode = p.Barcode,
Stock = p.Stock,
Price = p.Price
}));

await database.SaveChangesAsync(); // <---- DbUpdateConcurrencyException is thrown here
page++;
}
}
I am testing this from my local dev machine, so the only difference between crash and no crash is the connection string to the MySQL database, the rest of the environment is the same (I can access the remote DB through an SSH tunnel). I have a feeling that this issue has to do with the MySQL configuration on the prod server, but I can't figure out what it is. Despite the error, there is no actual concurrence, because this code doesn't run multiple times in parallel, and nothing else is reading/writing from/to the database while the app is running. What could be the cause of this exception, and why does it only happen on a linux-based MySQL installation?
1 Reply
Sparky
Sparky2y ago
Update: I used DataGrip's built in import/export tools to clone my local dev database to prod. It turns out that this tool is doing something funny, and doesn't replicate the DDL on the target exactly as it should be. I updated my deployment scripts to use the dotnet ef migrations script tool to generate an idempotent sql file to apply the migrations to prod, and it works now.