Параллельные запросы на обновление того же поля в ASP.NET Core с использованием Entity Framework Core - PullRequest
0 голосов
/ 27 октября 2019

Мое веб-приложение разработано с использованием ASP.NET Core 2.2 и Pomelo.EntityFrameworkCore.MySql 2.2.0. В запросе PUT я обновляю столбец в базе данных. Приведенный ниже код является моей демонстрацией:

[Produces("application/json")]
[Route("api/{id}/increment/{increment}")]
[HttpPut]
public async Task<IActionResult> PutIncrement([FromRoute] int id, [FromRoute] float increment)
{
    Model m = _context.Model
                      .Where(f => f.Id == id)
                      .SingleOrDefault();

    m.Value += increment;

    _context.Entry(m).State = EntityState.Modified;

    await _context.SaveChangesAsync();

    return Ok(m);
}

Затем я вызываю те же самые запросы (https://localhost/api/1/increment/1) 10 раз параллельно с 7 процессорами. Я ожидаю, что значение равно 10. Однако фактическое значениев базе данных гораздо меньше 10. (примерно 2-4). Как мне обрабатывать запрос один за другим в ASP.NET Core?

1 Ответ

2 голосов
/ 27 октября 2019

Вы можете реализовать Оптимистичный параллелизм

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

Его можно включить, добавив свойство RowVersion, как показано ниже

public class Model
{
     public int Id {get;set;}
     ........ // Other Properties
     public int Value {get; set;} 

     [TimeStamp]
     public byte[] RowVersion { get; set; }
}

Столбец RowVersion будет настроен как тип базы данных, который обеспечивает автоматическое управление версиями строк.

Теперь вы можете заключить метод SaveChangesAsync в try-catch для решения проблем оптимистичного параллелизма. Проверьте Документы Microsoft для получения более подробной информации.

try
{
    // business logic
    await _context.SaveChangesAsync();
    // Other business logic
}
catch (DbUpdateConcurrencyException ex)
{
    // your logic to handle optimistic concurrency.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...