Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Connection


Автор: PovAnd 1.4.2008, 12:26
Надо следующее:
Закрыть Connection, если он долго  не юзается. Например: пять минут прошло, а никто не сделал ни одного запроса, стало быть надо этот connection закрыть. Надо именно это.
Подскажите кто знает.

Автор: LSD 1.4.2008, 12:34
Сделай свой менеджер соединений, когда программе нужно выполнить запрос, она обращается к этому менеджеру и получает у него соединение, выполняет запрос и возвращает его. И уже в нем отсчитывай эти пять минут.

Или вообще используй готовый пул соединений, тот же http://commons.apache.org/dbcp/.

Автор: PovAnd 1.4.2008, 14:34
Реализовывать свой менеджер я конечно не стал, вместо этого вкурился в предложенный dbcp. И все таки не могу я найти, ту вещь что ищу. А конкретнее именно это:
Мне нужно убирать заброщенные соединения из пула. Я не создавал своего менеджера и потому, что на вскидку не могу себе  представить, как мне слегонца реализовать определение, того что коннекшен не используется. Будет например запрос на 15 минут, а я условно выставлю - считать не нужным после пяти минут и тогда ну и может получиться, что обрежу нормальный Connection. Может я чего-то не вижу, тогда в какой там стороне у DBCP это обрезание не нужных конекшенов?

Автор: LSD 1.4.2008, 14:59
Ты считаешь только время пока конекшн в пуле, пока он не в пуле время не учитывается. Естественно ты должен сделать так, чтобы  приложение получало конекшн только когда он действительно нужен и сразу возвращало, как только необходимость в нем отпала. Еще можно создать свою обертку над конекшеном, чтобы не использовать пул.

А вообще описал бы ты задачу, а то есть сильное впечатление, что мы тут придумываем свое, очень оригинальное, средство передвижения smile

Добавлено через 45 секунд
Цитата(PovAnd @  1.4.2008,  14:34 Найти цитируемый пост)
Может я чего-то не вижу, тогда в какой там стороне у DBCP это обрезание не нужных конекшенов?

Когда конекшен возвращется в пул, вот тогда и начинается отсчет времени.

Автор: PovAnd 1.4.2008, 15:19
Задача у меня  выглядит так:

Есть серверная часть.
Есть клиентская чать.

С клиента на сервер приходят параметры доступа к некоторой БД. Сервер делает Connection для этих параметров. Если все создалось удачно, то дальше клиент работает с Connection через интерфей сервиса, реализация которого на сервере. Нормальный клиент после того как поработает  через сервис с Connection, - сообщит, что больше он ему не нужен и тогда на сервере Connection будет закрыт и забыт. Но если так случится, что клиент по каким-то причинам не сообщил, что Connection ему больше не нужен, то нужен механизм, который все равно, через какое-то время, гарантировано прибьет ставший ненужным Connection.

Как-то пока я надумал только, приставлять к каждому коннешену таймер, и запускать его после конца каждого метода, который как я считаю - использующий Connection, тогда, если этот таймер будет ожидать более времени X , то Connection будет закрываться и удаляться. Но что-то как-то мне хочется это делать в последнюю очередь, если уж совсем ничего другого нет.

Автор: LSD 1.4.2008, 15:44
100% гарантированно рабочий метод, крайне трудоемок.

Создаем класс таймаут:
Код

public class Timeout
{
  public static final long TIMEOUT = 5 * 60 * 1000L;

  private volatile long lastAcessTime;
  private final long timeout;

  public Timeout()
  {
    this(TIMEOUT);
  }

  public Timeout(long timeout)
  {
    this.timeout = timeout;
    updateLastAcessTime();
  }

  public void updateLastAcessTime()
  {
    lastAcessTime = System.currentTimeMillis();
  }

  public boolean isExpired()
  {
    return System.currentTimeMillis() - lastAcessTime > timeout;
  }
}

Создаем свой врапер для конекшена:
Код

class TimoutConnectionWrapper implements Connection
{
  private Timeout timeout;
  private Connection conn;

  public TimoutConnectionWrapper(Connection conn, Timeout timeout)
  {
    this.conn = conn;
    this.timeout = timeout;
    timeout.updateLastAcessTime();
  }

  public Statement createStatement() throws SQLException
  {
    Statement statement = new TimeoutStatementWrapper(conn.createStatement(), timeout);
    timeout.updateLastAcessTime();
    return statement;
  }

  public PreparedStatement prepareStatement(String sql) throws SQLException
  {
    PreparedStatement statement = new TimeoutPreparedStatementWrapper(conn.prepareStatement(sql), timeout);
    timeout.updateLastAcessTime();
    return statement;
  }
....

аналогично для всех интерфейсов из java.sql/javax.sql.

Далее при конекте клиента создаешь Connection, создаешь Timeout, оборачиваешь Connection в TimoutConnectionWrapper, кладешь это дело в Map<Timeout, Connection> и отдаешь клиенту обернутый конекшн. Затем надо только переодически проверять все Timeout-ы, и для истекших прибивать Connection.

Автор: PovAnd 1.4.2008, 15:46
Благодарю!

Автор: mbasil 1.4.2008, 16:21
1. Как справедливо заметил LSD обычно так, как Вы предполагаете, на серверах приложений не поступают с подключениями. При необходимости получения подключения, при каждом запросе пользователь получает подключение только на время выполнения ответа на запрос, а затем подключение закрывается логически. При этом оно возвращается в пул. Реализация пула, а dbcp, как это следует из его названия уже является пулом сама должна заботиться о физическом закрытии неиспользуемых подключений. То есть нет смысла напрягаться с таймерами и обертками.

2. Если Вы не хотите использовать стандартный пул, а хотите держать подключение  долго (или не используете сервер приложений) бросьте мне письмо. Когда то во времена, когда пулов было мало я нашел в Интернете исходный текст пула с обертками подключений и немного его сам доработал. Если хотите могу закинуть текст. Там запускается поток мониторинга для отслеживания простаивающих подключений.  

Автор: COVD 1.4.2008, 21:19
Цитата(mbasil @ 1.4.2008,  16:21)
1. Как справедливо заметил LSD обычно так, как Вы предполагаете, на серверах приложений не поступают с подключениями. 

Тут с самого начала оригинально:

Цитата

С клиента на сервер приходят параметры доступа к некоторой БД.


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

Автор: PovAnd 2.4.2008, 11:49
В том то и дело, что задача не совсем такая с какой обычно приходится иметь дело. Я понимаю для чего нужен предлагаемый пул, он бы был уместен, если бы сервер всегда знал, какие именно параметры подключения у него будут просить. У меня же параметры доступа к БД  - это абсолютно левые Базы Данных, которые каким-то макаром интересуют пользователя, не имеющие никакого отношения к моему приложению, сервер здесь всего лишь пытается влезть в эти базы и по запросу пользевателя чего-то там взять. 


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

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

Буду весьма благодарен. Если можно, то вышлите на этот адрес [email protected]

Автор: COVD 2.4.2008, 15:46
Можно на запрос к новой базе создавать новый пул и класть его в мап. И переложить головную боль с закрытием соединений на пул. Количество возможных баз данных наверняка не слишком велико - это же не сайты в интернете. Они обычно в локальной сети. Странная архитектура. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)