До того, как я начал, я не мог найти никаких других ресурсов, чтобы ответить на мой вопрос, самый близкий: Вызов хранимой процедуры одновременно из нескольких потоков в asp.net и sql server 2005 но он не отвечает на мою конкретную проблему / проблему.
По сути, у меня есть массивное веб-приложение .net, которое обрабатывает миллионы запросов в день.
Предположим:
- Все рассматриваемые sprocs являются простыми get sprocs (например, ВЫБРАТЬ [ЧТО-ТО] ИЗ [КУДА-ЛИБО] ВНУТРЕННЕГО СОЕДИНЕНИЯ [ЧЕГО-ЛИБО] и т. Д ....)
- Все данные никогда не изменяются(время от времени оно меняется, ради моего сценария, предположим, что это не так)
- Кэш изначально пуст по любой причине.
рассматриваемый метод: Я проверяю наличие объекта в кеше приложения.Если он существует, я просто возвращаю его.Если объект не находится в кеше, в базу данных выполняется вызов sproc для поиска этих данных.Как только sproc возвращается, эти данные добавляются в кэш, а затем возвращаются.
При большой нагрузке у меня возникла проблема с производительностью, которую я хотел бы устранить.
Вот мой сценарий:
- Пользователь A входит в этот метод.
- Данные не находятся в кэше, вызывается sproc.
- Пользователь B входит в этот метод (пока sproc все еще работает).
- Данные не находятся в кэше, вызывается sproc.
- Промывайте и повторяйте снова и снова.
При большой нагрузке они могут генерировать довольно много одновременных и избыточных активных спидов.Я пытаюсь найти лучший способ обойти это.Очевидно, что я мог бы добавить sp_getAppLock, но запросы все равно заканчивались бы: 1) попаданием в sproc и 2) должно запускать точно такой же запрос.Я мог бы заблокировать объект, специфичный для этого точного запроса и обернутый вокруг проверки кэша.Но если я сделаю это, я потенциально открою дверь для некоторого массивного разногласия и тупиковой ситуации.
Я должен предположить, что кто-то имел дело с этим самым сценарием ранее, и я надеюсь, что есть соответствующее решение,Прямо сейчас лучшее решение, которое я могу придумать, - это блокировка приложений, но мне бы очень хотелось узнать, есть ли у кого-нибудь лучшие варианты.Возможно комбинация вещей, скажем, блокировки приложений sql и обмена сообщениями (традиционная или нетрадиционная), где после успешной блокировки любая, которая только что была освобождена, пытается сбросить набор результатов (откуда?), В отличие от повторного выполнения всегоостальная часть sproc.
РЕДАКТИРОВАТЬ: Так что следуйте этому ... Если я блокирую или "жду" либо кеширования, либо вызова sproc, то при большой нагрузке возможно, что если элемент не кэшируется, а метод (или sproc) генерирует объект, который будет кэшированможет занять больше времени, чем ожидалось.Пока это уходит, потокам придется подождать.Ожидание, единственный способ (по крайней мере, я знаю), чтобы заблокировать или вращаться.Разве тогда невозможно исчерпать пул потоков или заблокировать все доступные запросы и заставить запросы ставиться в очередь?Это мой страх и то, что заставило меня задуматься о том, чтобы перенести слой из приложения в базу данных.В прошлый раз, когда мы пытались заблокировать кэширование, мы страдали от резких скачков ЦП в нашем веб-боксе, потому что потоки так долго находились в состоянии блокировки.Хотя я считаю, что в то время мы не использовали Monitor.Enter / Monitor.Exit (или просто lock () {}).В любом случае, у кого-нибудь есть какие-либо подробности или опыт в этой области?Я знаю, что по этой самой причине блокировать долго работающие процессы обычно очень плохо.Я бы страдал от загрузки дублирующегося контента в кэш, если бы не мог предотвратить попадание пользовательских запросов в очередь запросов, потому что у меня нет потоков или все активные запросы заблокированы.Или, может быть, уже поздно, и я уже обдумал это.Я начал свой день с почти блестящего момента "ах-ха".Но теперь я продолжаю догадываться.