Повторяющееся значение ключа нарушает уникальное ограничение для SaveChangesAsync - PullRequest
0 голосов
/ 21 октября 2019

У меня есть следующий код в контроллере

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();
}

Трудно воспроизвести, но иногда я получаю

23505: дублирующее значение ключа нарушает уникальное ограничение \ "devices_imei_key \"

Кажется, что device равно нулю, но когда SaveChanges уже не равно нулю. Как я могу справиться с этим, избегая использования try...catch? Могу ли я использовать AsNoTacking() для улучшения чтения из базы данных?

1 Ответ

1 голос
/ 21 октября 2019

Это базовый параллелизм, и, как всегда, вам нужно иметь особую стратегию обработки параллелизма. Используемый в настоящее время метод недостаточен, если вы не зададите логику, так что только один запрос может проходить через конвейер одновременно с использованием семафора. Это обходит проблему параллелизма, но, очевидно, влияет на производительность, так как вы создаете в своем приложении точку подавления.

Лучшая ставка здесь, поскольку у вас есть уникальное ограничение, заключается в переносе кодав попытке / поймать и фактически обработать сценарий, с которым вы столкнулись. Поскольку для каждого IMEI должна быть только одна запись, вы можете просто сделать то же самое, что и в блоке else для блока catch: вернуть ConflictException.

Для этой конкретной проблемы естьникаких других опций, кроме добавления блокировки или обработки исключения (используя try / catch). Неважно, насколько «быстро» вы идете, всегда есть вероятность потенциального конфликта параллелизма, и вам придется справиться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...