У меня есть веб-приложение, в котором пользователи могут публиковать предложения для продуктов.
Иногда - менее 1 в 10 случаях - сохранение предложения приводит к нескольким записям в базе данных с идентичными данными (обычно 2 записи, но3 или даже 4 идентичных записи уже произошли).
Класс предложения - это простой класс сущности с некоторыми свойствами в нем.Он также связан с двумя другими классами сущностей OfferImage и OfferCategory, которые хранят связанные изображения и категории, в которых должно появиться предложение.
Код для сохранения элемента в базе данных следующий (частькласс репозитория):
public class OfferRepository {
...
public async Task InsertAsync(Offer offer)
{
Context.Offer.Add(offer);
await Context.SaveChangesAsync();
}
...
}
Он вызывается внутри класса обслуживания:
public class OfferService
{
...
public async Task CheckinAsync(Offer offer)
{
await repository.InsertAsync(offer);
}
...
}
Этот метод этого класса обслуживания вызывается контроллером MVC:
public async Task<IActionResult> Create(CreateOfferViewModel createOfferViewModel)
{
if (ModelState.IsValid)
{
...
//conversion of the view model object to an Offer object
...
await offerService.CheckinAsync(offer);
}
...
}
Как видите, структура относительно проста.Однако эта ошибка происходит регулярно.
Жизненный цикл классов обслуживания управляется с помощью внедрения зависимостей в startup.cs.OfferRepository и OfferService добавляются в области видимости (services.AddScoped). Контекстный класс добавляется следующим образом:
services.AddDbContext<Context>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("DataConnection"),
sqlServerOptionsAction: sqlServerOptions =>
{
sqlServerOptions.EnableRetryOnFailure(maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(3), errorNumbersToAdd: null);
}
);
});
Чтобы еще больше сузить проблему, я запустил профилировщик и получил запись операторов INSERT (вхронологический порядок):
- SPID 59 - 2019-09-24 16: 05: 19.670 - ВСТАВИТЬ INTO ПРЕДЛОЖЕНИЕ ...
- SPID 57 - 2019-09-24 16:05: 19.673 - INSERT INTO Offer ...
- SPID 59 - 2019-09-24 16: 05: 19.710 - INSERT INTO OfferImage ... / INSERT INTO OfferCategory ...
- SPID 57- 2019-09-24 16: 05: 19.760 - INSERT INTO OfferImage ... / INSERT INTO OfferCategory ...
Что вызывает у меня подозрение, так это два разных идентификатора процесса, которые выполняют INSERT,Поскольку DbContext ограничен по умолчанию, должен быть только один идентификатор процесса, под которым выполняются все государственные деятели - или я ошибаюсь?Если я не ошибаюсь, это будет означать, что два запроса выполняются параллельно, что, в свою очередь, вызывает дополнительные вопросы о том, как это может произойти.
Как видите, я немного растерялся и надеюсь на помощькто-то, кто может объяснить это или наблюдал и решил что-то подобное.
(SQL Server - версия 13/2016, EF Core - версия 2.2)
Большое спасибо!