Иногда карта структуры возвращает неверный объект, это происходит, когда данный веб-сервер, на котором размещено наше веб-приложение, находится под большой нагрузкой. Рассматриваемый объект - это наш собственный класс, содержащий свойства для имени сервера и базы данных, которые используются для построения строки соединения.
Наше веб-приложение состоит из 2 частей: раздела веб-форм ASPX, который интенсивно использует сеанс, и новой части в MVC, которая находится в области проекта веб-форм. Обе эти области используют одну и ту же сессию. Информация о подключении к базе данных создается при входе в систему и сохраняется в сеансе. Область веб-форм напрямую получает информацию базы данных из сеанса, и это прекрасно работает.
Dim dbInfo as DbInfo = me.Session("dbInfo")
Область MVC получает информацию о базе данных, вводимую через карту структуры, которая, в свою очередь, получает объект из сеанса.
Public Class WebRegistry
Inherits Registry
Public Sub New()
[For](Of IDbInfo)().HybridHttpOrThreadLocalScoped().Use(Function() GetDatabaseInfoFromSession())
End Sub
<CLSCompliant(False)>
Public Shared Function GetDatabaseInfoFromSession() As IDbInfo
If HttpContext.Current.Session("dbInfo") IsNot Nothing Then
Return HttpContext.Current.Session("dbInfo")
End If
Return Nothing
End Function
End Class
Как видно из приведенного выше кода, оба обращаются к одной и той же переменной в сеансе и, по-видимому, большую часть времени возвращают одно и то же значение. Но, похоже, происходит некоторое кэширование, поскольку проблема заключается в том, что старый код использует правильное соединение (то, с которым пользователь вошел в систему), а метод структурной карты, похоже, кэширует другое соединение с базой данных.
То, как мы моделировали то же самое поведение, заключается в том, чтобы вручную создавать экземпляр dbInfo в функции GetDatabaseInfoFromSession для другой базы данных.
Обратите внимание, что этот код находится в разработке уже более года, и у нас есть предыдущие версии кода на тех же веб-серверах, которые работают отлично. Последняя версия сайта начала демонстрировать это странное поведение кеширования на прошлой неделе. Известные вещи, которые недавно изменились:
Пул приложений, на котором работает сайт, теперь 64-битный
Были установлены новые балансировщики нагрузки Kemp.
Вещи, на которые мы уже смотрели:
В чем разница между HybridHttpOrThreadLocalScoped и HttpContextScoped (мы ничего не делаем с потоком, поэтому считаем, что это нормально)
Разница между Session и HttpContext.Current.Session (у нас есть нулевая проверка в GetDatabaseInfoFromSession, и наш старый код не генерирует HttpException)
Запускает ли карта структуры кэширование на уровне компьютера, если он загружен с включенной 64-битной версией, или карту структуры путают с активными сеансами?