Как создать одно соединение с базой данных на пользователя в приложении Java Servlet? - PullRequest
1 голос
/ 24 июля 2011

Я работаю над веб-сайтом с использованием Java-сервлетов, и мое исследование показало, что лучше всего поддерживать одно соединение с базой данных на пользователя (вместо того, чтобы только одно соединение постоянно находилось в фоновом режиме или подключаться к базе данных каждый раз, когдасделка должна быть сделана).Однако я не знаю, как этого добиться.То, что я сейчас делаю, - это мой класс объекта доступа к данным. У меня есть

private static Connection conn;

, и у меня есть событие HTTPSessionListener - on sessionCreated, которое я подключаю к базе данных, используя эту статическую переменную "conn",и при sessionDestroyed событии я отключаю переменную "conn":

... в моем "MySessionListener" ...

public void sessionCreated(HttpSessionEvent sessionEvent) {
    System.out.println("Session created!");
    DAO.connect();

}

public void sessionDestroyed(HttpSessionEvent sessionEvent) 
{
    System.out.println("Session destroyed");
    String user = (String) sessionEvent.getSession().getAttribute("userid" );
    if (user != null) DAO.signUserOut(user);
    DAO.disconnect();
}

Теперь проблема в том, что:

  1. Я боюсь, что таким образом я существенно ухудшу, что у меня будет только одно соединение, которым все делятся (вместо соединения на пользователя, как я хотел), просто время от времени я отключаюсь, если нет пользователей.Правильно?
  2. Если несколько пользователей находятся в сети и один закрывает их сеанс, они будут закрывать соединение для всех, пока кто-то еще не начнет сеанс и не создаст новое соединение для всех, верно?Я не могу проверить это очень хорошо, потому что я тестирую это локально на своем ноутбуке с 3-мя браузерами, но даже когда я закрываю браузер, на котором был мой веб-сайт, сеанс не сразу прекращается, и я не уверен, что именно происходит,Все, что я знаю, это то, что иногда я получаю исключение, в котором говорится: «После закрытия соединения транзакции запрещены».

Ответы [ 2 ]

5 голосов
/ 24 июля 2011

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

См. Это (довольно универсально) Статья в Википедии .

Некоторые известные пулы DBCP и C3P0 .

2 голосов
/ 24 июля 2011

Здесь есть две проблемы:

  • Тайм-аут сеанса http
  • Подключение сеанса базы данных

Кажется, вы смешиваете две концепции сеанса.

HTTP-сеанс

Вам необходимо дополнительно ознакомиться с механизмом http клиент-сервер.Закрытие браузера не закрывает сеанс http.Когда вы закрываете браузер, вы должны закодировать на своих страницах «при закрытии»."На близком" ??Абсолютно нет - в html / javascript нет такой вещи, как onclose.Но есть onunload (как и onload).

Почему в javascript / html нет «onclose»?Я думаю, что люди, которые изобрели http / html, были параноиками по многим непредвиденным обстоятельствам.Возможно, это правильно.Возможно, нам нужно понять образ мыслей и мотивацию изобретения html / http.Таким образом, у вас нет выбора, кроме как придумать цепную реакцию событий onunload.ONUNLOAD / ONLOAD - это события html-страницы, а не события браузера.Весь механизм HTML управляется страницей, а не браузером.Поэтому, когда вы закрываете браузер, он вызывает событие onunload для каждой вкладки в браузере.

Вам придется использовать страницу onunload, чтобы сообщить серверу, что пользователь намерен закрыть сеанс.В противном случае сервер должен зависеть от значения времени ожидания сеанса, чтобы завершить сеанс.Что если пользователь закроет браузер на одной из ваших страниц, на которой вы не написали код в событии onunload?Очень жаль - вот почему я написал «придумать цепную реакцию onunload» на каждой странице.Что очень утомительно и надоедливо.

Иногда.особенно для очень математических сервлетов серверу требуется много времени для ответа.Затем на странице клиента потребуется указание, чтобы отличить сервер, все еще обрабатывающий ответ, от сервера, который вышел из строя - тайм-аут сеанса, установленный в браузере.например, http://support.microsoft.com/kb/813827 (Как изменить значение времени ожидания сохранения по умолчанию в Internet Explorer).

Может быть, сервер должен время от времени тыкать в страницу браузера, чтобы проверить, работает ли браузерсессия еще жива.Нету.Http - технология вытягивания клиента.Сервер не может отправить ответы клиенту.Почему бы и нет?Почему так глупо?Вы должны прочитать весь http / html образ мыслей / паранойю, чтобы понять.Браузер может тыкать в сервер, но не наоборот.

Поэтому AJAX и комета были изобретены / придуманы.Имитировать, притворяться на сервере нажатием.С ajax у вас есть некоторые средства для сервера, чтобы psuedo-poke на клиенте.И это то, что вы должны сделать - используйте ajax, например, jquery или gwt.Я предпочитаю gwt.

Что если на клиентском компьютере произошел сбой питания, или ОС коснулась синего экрана, или процесс браузера был внезапно прерван?Не было бы возможности вызвать событие onunload ни для одной из страниц.

Сеанс соединения с базой данных

Ответ Алекса ударил по гвоздю - пул соединений.Однако бывают ситуации, когда мне нужно иметь соединение с базой данных на сеанс.Хммм ... как мне это сделать?Да, я сохраняю соединение как атрибут сеанса.Следовательно, будет столько же соединений с БД, сколько и сессий.Что, по сути, имеет тот же эффект, что и то, что вы делаете в настоящее время.

Разработка веб-приложений с отслеживанием состояния для клиентов без учета состояния (несмотря на файлы cookie) и предположительно нестабильных клиентов требует осторожности.Что делать, если пользователь нажимает кнопку «Назад» после выхода из системы?Страница back / prev может содержать действие, которое заставляет сервер использовать соединение БД, которое уже было закрыто страницей выхода до того, как пользователь нажал кнопку «Назад».Или это может быть тайм-аут сервера из-за того, что клиент не ткнул в сервер в течение времени, превышающего значение тайм-аута активности сеанса.

Поэтому, прежде чем разрабатывать «многоуровневое» клиент-серверное приложение, вы должны сесть и составить список всех непредвиденных обстоятельств, с хорошим пониманием мышления / паранойи технологии http.Вы должны заразить себя навязчивыми идеями http, чтобы создавать свои приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...