При использовании EF Core 2.1 DbContext в функции Azure QueueTrigger я получаю исключение нарушения PK.Вероятно, это связано с тем, что DbContext не является поточно-безопасным , а функция Azure параллельно запускает разные экземпляры.Я прочитал довольно много, но не могу найти хороший подход для решения этой проблемы.
Вот мой сценарий (шаблон производитель-потребитель):
У меня есть ЗапланированоФункция Azure , которая вызывает API для получения проектов из разных внешних систем.Чтобы получить всю необходимую информацию для проекта, мне нужно запустить другие запросы к другим внешним службам, поэтому я отделяю это от другой функции Azure, поэтому функция «Запланировано» просто помещает сообщение в очередь для каждого проекта, например « Sync Project».ID 101 ”.
Другая Функция QueueTrigger срабатывает каждый раз, когда сообщение ставится в очередь, поэтому это означает различные экземпляры, работающие параллельно .Эта функция должна собирать все данные определенного Проекта , а это означает, что нужно больше обращений к другим внешним службам / API, чтобы (каким-то образом) объединить всю информацию о Проекте .ИМХО, это хорошо сделать так, так как я могу обрабатывать несколько проектов параллельно, и я могу масштабировать функцию, если мне это нужно.
Как только у меня будет все это Project infoЯ хочу сохранить его в базе данных SQL с использованием EF Core (и здесь возникает проблема)
Данные проекта включают в себя пользователей в проекте, и каждый пользователь имеет определенный GUID в качестве PK (исходя из внешней системы).Это означает, что у меня могут быть повторные идентификаторы пользователей в разных экземплярах функций, и здесь возникает проблема, так как при попытке сохранить информацию о пользователе в таблице SQL я могу получить исключение дублирования PK, так как несколько экземпляров функций могут пытаться вставить одного и того же пользователяв то же время (когда экземпляр A проверяет, существует ли пользователь, он получает значение False, но другой экземпляр B фактически добавляет этого пользователя, поэтому, когда экземпляр A пытается выполнить вставку, происходит сбой).
Думаю, я могу заблокироватьDbContext каким-то образом, но не уверен, что это хорошо, так как у меня также есть веб-сайт, выполняющий запросы к базе данных SQL (запросы только для чтения на данный момент, но могут быть обновления и в будущем).
Другая идея может состоять в том, чтобыотправить всю информацию о проекте в другой файл очереди / большого двоичного объекта и иметь другую функцию в режиме Singleton , которая вставляет данные в SQL.
Я создал этот проект, упрощая мой сценарий, но достаточновоспроизвести проблему и понять проблему.https://github.com/luismanez/queuetrigger-efcore-multithreading
Есть еще идеи или рекомендуемые подходы?(откройте для изменения архитектуры, если найдете что-то лучшее)
Большое спасибо!