Хранение соединения JDBC в HttpSession

Я недавно наследовал некоторый код, в рамках которого я нашел соединение JDBC, инициализируемое в фильтре, и добавил HttpSession для каждого пользователя. То соединение затем снова используется всюду по различным частям веб-приложения для пользователя. Это сразу выделилось мне как запах кода. Я хотел бы вернуться к разработчику, который записал это, и объясните, почему он не должен делать этого... Но возможно я не так уверен сам...

Помимо занимания ненужного места в памяти и потенциально ограничении доступных соединений с базой данных, там какие-либо другие причины, почему Вы не сохранили бы соединение JDBC на сессии?

5
задан BalusC 15 July 2010 в 12:08
поделиться

3 ответа

Вы упомянули очевидное, один пользователь к одному соединению с базой данных не масштабируется. Ваши пользователи должны быть полностью отделены от доступа к модели данных. Вот несколько проблем, с которыми вы столкнетесь.

  • Что произойдет, если соединение станет неактуальным? Пользователь не сможет сделать ничего полезного без соединения с базой данных, поэтому ему, скорее всего, придется выйти из системы, а затем снова войти, чтобы получить новое соединение. Безумие.
  • Соединения JDBC не являются потокобезопасными. Если пользователь решит запустить несколько вещей одновременно, то начнется полный ад.
5
ответ дан 14 December 2019 в 04:29
поделиться

Сама идея поддерживать соединения JDBC на таком же высоком уровне в стеке, как в HttpSession или даже получать доступ к соединениям JDBC на уровне сервлетов, не имеет большого смысла. Гораздо разумнее объединить соединения на сервере приложений и таким образом уменьшить количество открытых соединений. Тогда одно и то же приложение сможет обслуживать гораздо большее количество одновременных пользователей с гораздо большей производительностью.

В большом приложении маловероятно, что все запросы попадут в базу данных, поскольку одна и та же информация может быть найдена в кэше в любом случае.

В кластерной среде с незакрепленными сеансами соединение JDBC не будет даже действительным, если запрос попадет в другое поле, кроме того, в котором был создан сеанс.

В общем, вы должны хранить в сеансе только информацию, специфичную для пользователя, и даже в этом случае уменьшить количество, необходимое в сеансах, до минимума. Больше данных в сеансе означает больше данных для передачи между серверами приложений в кластере при репликации сеансов (в случае, если сеансы не хранятся в центральной БД или в кеше).

2
ответ дан 14 December 2019 в 04:29
поделиться

Хотя я не могу знать, я рискну предположить, что ваш коллега начинал с того, что каждый запрос получал новое соединение от менеджера, как это делается в программах для начинающих и демонстрационных программах. Вскоре он обнаружил, что это значительно замедляет запросы; поэтому теперь он избегает создания соединений, "объединяя" их в пользовательские сессии.

Это решает проблему производительности для пользователей, делающих второй и последующие запросы через соединение, но это очень неудобное и немасштабируемое решение. Если пользовательская база вашего приложения будет расти, количество пользователей с открытыми сессиями быстро перерастет максимальное количество соединений, которое может предоставить вам ваша БД. А потом возникнут проблемы с таймингом сессий или соединений с БД...

Стандартным решением в индустрии является использование пула соединений. Современные версии Tomcat имеют "встроенный" пул соединений, как и другие серверы веб-приложений. Если нет, вы можете легко установить свой собственный. Это позволяет вам управлять пулом соединений совершенно независимо от пользовательских сессий.

Еще одним преимуществом пула соединений является то, что, как только пул "разогрет", т.е. несколько соединений используются и инициализируются, даже "первые запросы на пользовательскую сессию" быстро получают соединение. Таким образом, общая пропускная способность будет улучшена по сравнению с вашей текущей ситуацией.

1
ответ дан 14 December 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: