Duplicate key value violates unique constraint on SaveChangesAsync

asp.net-core-webapi c# entity-framework-core

Question

I have the following code in controller

public async Task<IActionResult> Post(string imei)
{
    var device = await _dbContext.Devices.FirstOrDefaultAsync(x => x.Imei == imei);
    if (device == null)
    {
        await _dbContext.Devices.AddAsync(new Device(imei));
        await _dbContext.SaveChangesAsync();
    }
    else
    {
        throw new ConflictException($"Device with IMEI '{imei}' already exists");
    }

    return Ok();
}

It is hard to reproduce but sometimes I got

23505: duplicate key value violates unique constraint \"devices_imei_key\"

It seems that device is null but when SaveChanges it is already not null. How can I handle it avoid using try...catch? Can I use AsNoTacking() to improve reading from database?

1
0
10/21/2019 2:54:21 PM

Accepted Answer

This is basic concurrency and as always, you need to have a specific strategy for handling concurrency. The method you're currently using is insufficient unless you gate the logic, such that only one request can go through the pipeline at a time, using a semaphore. That skirts the issue of concurrency, but obviously has an impact on performance, as you're creating a choke point in your application.

Your best bet here, since you have the unique constraint, is to wrap the code in a try/catch and actually handle the scenario you're facing. Since there should only be one entry for each IMEI, you can simply do the same as you're doing in the else block for the catch block: return a ConflictException.

For this particular issue, there is no other options but adding a lock or handling the exception (using try/catch). It doesn't matter how "fast" you go, there is always a potential for a concurrency conflict, and you'll need to handle that.

1
10/21/2019 3:59:14 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow