У меня есть главный сервлет контроллера, в котором я создаю источник . Сервлет открывает и закрывает соединения. В основном, сервлет создает команду из приложения, используя «фабричный шаблон». здесь некоторый код, чтобы объяснить:«Ленивая инициализация» соединений jdbc из jdi datasource/pool pool: осуществимость
public void init() throws ServletException {
super.init();
try {
datasource =(DataSource) getServletContext().getAttribute("DBCPool");
}
catch (Exception e) {
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//some code...
Connection connection = null;
if(cmd.mightNeedLazyLoadingAConnection)
{
connection = null;
}
else
connection = getConnection();//where getConnection is a method: datasource.getconnection();
//now a command (a java class) is instantied, to which the "null" CONNECTION obj is passed as parameter
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,connection);
//some code
//Then wherever there is catch exception i close() the connection
// and it is always closed in finally
finally {
if(connection!=null)
connection.close()
}
}
Теперь это имеет проблему для первого случая, то есть связи = нуль, так как он не имеет и не закрывает соединение в «наконец» части (объяснил, почему в Обновление ниже). «Соединение = нуль»
для случаев, когда команды не может понадобиться, чтобы открыть соединение с базой данных, поскольку данные он ищет кэшируются в identity map.
Я пытался передать "Соединение" OBJ в качестве "нулевого" параметра в .Execute (TSK, соединение);, а затем в соответствующем классе Java, чтобы открыть соединение если необходимо
-> он сделал открыть соединение внутри команды, однако, когда процесс переходит обратно к сервлету: «Соединение» является недействительным, поскольку при этом не закрыто.
Что я могу сделать, чтобы сделать «Подключение» Значение obj обновляется, поэтому, когда он снова находится в сервлете, он больше не «Null», и я мог бы его закрыть?
Я вообще предпочитаю использовать сервлет контроллера, который открывает/закрыть соединения дБ, так что было бы лучшим способом справиться такого рода сценарий, в котором вы должны сделать какой-то «отложенной загрузки» а соединение с базой данных из бассейна и в то же время сохранить открытие/закрытие соединения db, назначенного сервлету?
Update (объяснить далее):
- говорят, у меня есть команда: X.java
- эта команда может/не может требуется подключение дБ (зависит, если данные поиск которых находится на идентификационной карте или нет)
Система, которую я хотел бы иметь:
(1) "запрос клиента"
(2) --->"Servlet": command.execute (соединение) // где соединение = нуль на текущий
(3) --->«Команда X»: Нужно ли мне переходить в базу данных или запись находится в карте идентификации?
(3.а) Случай, когда это необходимо, чтобы перейти к базе данных:
подключения (3.А.1) = datasource.getconnection
(3.a.2) идут получить данные
(4) - ->назад в сервлет: близко «соединение» в «Servlet»
Прямо сейчас он не работает до тех пор (3.a.2), но когда-то еще в (4), то оказывается, что соединение по-прежнему " null "и, следовательно, код:
finally {
if(connection!=null)
connection.close()
}
не работает (не закрывает соединение) и, таким образом, пул db так истощается. Каким образом соединение - которое начинается как «null» и изменяется внутри команды «X» - обновляется «globaly» до его нового значения, а не только «обновляется» внутри области действия команды «X»?
РАСТВОР (S)
В случае, если вы сталкиваетесь с таким же сценарием, вы можете выбрать из этих -решений:
Вы можете использовать LazyConnectionDataSourceProxy как упоминался на @Ryan Stewart за «чистую абстракцию» и более профессиональное решение
Или, если вы хотите использовать мое решение, описанное ниже (в основном я реализовал класс, похожий на «LazyConnectionDataSourceProxy», но это не так чиста, она имеет меньше абстракции деталей, чем «LazyConnectionDataSourceProxy»)
Мой личный решение, Детали:
- Я создал класс «Helper», который конструктор принимает «источник данных» в качестве параметра
- Этот вспомогательный класс имеет методы: «Ленивый получить» соединение с бассейном, "Клоса e "connection
- Этот класс создается при помощи сервлета, и он получает соединение с бассейном Только при необходимости в приложении.
Это код, я добавил/модифицирована в сервлет:
Connection connection = null;
if(cmd.mightNeedLazyLoadingAConnection)
{
helper hp = new helper(datasource);
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,hp);
}
else
{
connection = getConnection();
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,connection);
}
Тогда говорят в команде "X", требуется подключение дб я сделать:
Connection connection = hp.LazyGet();//Now got a connection from the pool
И таким образом, когда поток процесса возвращается к уровню сервлета, я могу:
- Закрыть
- Откат
- commit
- и т.д ..
Все на этом объекте hp вспомогательного класса.
Какие преимущества я получаю от этого:
- ограничиваю всех баз данных открытия/закрытия/фиксации/отката в один место, то есть сервлет, который является ответственным за выполнением команд ,
- Имея случаев: никогда не нуждается в дб/всегда нуждается в дБ/может понадобиться дб теперь, таким образом я уменьшил звонки в базу данных 1/3, что довольно много, зная, что вызов базы данных растет экспоненциально с новыми функций и регистрации новых пользователей.
Это не может быть Cleanest обходной путь, но между этим способом и имеющие дополнительные «лишние» звонки 1/3 базы данных, это, безусловно, лучше. Или просто используйте LazyConnectionDataSourceProxy, если вы хотите Протестированный, абстрактный и чистый метод.
спасибо за советы. Я только что опубликовал свое решение несколько минут назад. Я не использую фреймворки, но я сделал какой-то класс помощника/прокси (проверьте мой ответ). – shadesco
Я ничего не говорил об использовании фреймворка. «LazyConnectionDataSourceProxy» делает почти то же самое, что описывает ваше решение, за исключением того, что он скрывает грязные детали за чистым уровнем абстракции. Нет понятия «может понадобиться соединение» или «ленивый get». Вы просто относитесь к нему как к нормальному 'DataSource', который обеспечивает нормальное' Connection', и вы получаете ленту бесплатно. Это значительно лучший вариант по этим причинам. –
Я вижу .. я перепроверю его и узнаю больше об этом – shadesco