Skip to content

MySQL FK constraint failures with BulkSaveChanges / BulkInsert under parallel partitions (works with SaveChanges and with Oracle provider) #631

@alfredjchiong

Description

@alfredjchiong

Environment
• EF Core: 7
• EntityFramework-Extensions (ZZZ Projects): 7.103.8
• Provider: Pomelo.EntityFrameworkCore.MySql – version 7.0.0
• MySQL Server: 8.0.0
• OS / Runtime: Windows 11 / Debian 12 Containers (.NET 7)
• AutoDetectChangesEnabled: <true/false> (please see note below)

When inserting related entities (parent/child with FK) using either BulkSaveChanges or BulkInsert while processing partitions in parallel, MySQL throws:
MySqlConnector.MySqlException (0x80004005): Cannot add or update a child row: a foreign key constraint fails (FBS_SanJose.FBS_CONTABILIDADES.MOVIMIENTOCONTROL_TRANSFINT, CONSTRAINT FK_MOVIMIENTOCONTROL_TRANSFINT_MOVIMIENTOCONTROL FOREIGN KEY (SECUENCIALMOVIMIENTOCONTROL) REFERENCESFBS_NEGOCI…)

The same code path does not fail when:
• We switch the provider to Oracle (same data and entity graph).
• We run with regular SaveChanges (no bulk).
• We keep bulk ops but avoid parallel execution (single partition / serialized flow).

This points to a MySQL-specific interaction of bulk operations + parallelism + FK checks.

This is a simplified sample of code:

// partition parameters into N partitions and run all in parallel
await Task.WhenAll(
    Partitioner.Create(parametros)
        .GetPartitions(degreeOfParallelization)
        .AsParallel()
        .Select(AwaitPartition));

async Task AwaitPartition(IEnumerator<Parametro> partition)
{
    using var scope = _services.CreateScope();
    var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();

    var parents = new List<MovimientoControl>();          // parent rows
    var children = new List<MovimientoControlTransfInt>(); // child rows referencing parent PK

    // ... populate parents & children with proper FK values ...

    // Variant A
    db.BulkInsert(parents);
    db.BulkInsert(children);

    // Variant B
    db.AddRange(parents);
    db.AddRange(children);
    db.BulkSaveChanges();
}

Only under the parallel partitions does MySQL raise the FK violation during the bulk statements (not always).

What we verified
• Entity and DB schema FK mapping is correct; the FK SECUENCIALMOVIMIENTOCONTROL references the parent PK and works with SaveChanges and Oracle provider.
• Setting degreeOfParallelization = 1 (i.e., no effective parallelism) avoids the error.
• The exception occurs for both BulkInsert (parents then children) and BulkSaveChanges.
• In all cases, regular SaveChanges with the same graph succeeds (suggesting ordering in the change tracker is fine when not using bulk).

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions