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

Допустим, есть этот код, который находится на стороне сервера:

class Foo {
    void doSomething() {
        try (Connection c = dataSource.getConnection()) {
            executeSQL(c);
            externalApiCall(); // this can be slow
            executeSQL(c);
        }
    }
}

Проблема здесь в том, что externalApiCall() может быть очень медленным, и он держит много соединений с базой данных открытыми (даже если они не используются), и это может привести к исчерпанию максимального количества соединений. Это будет вредно для других частей моего приложения, которые не зависят от какого-либо внешнего API, и я хочу этого избежать.

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

Итак, мой вопрос: есть ли какая-нибудь хорошая библиотека пула соединений, оболочка или что-то, что может хорошо справиться с такой ситуацией? Например, что-то, что открывает реальное соединение с базой данных только при создании объекта Statement и затем автоматически закрывает соединение при закрытии Statement. В настоящее время я использую Tomcat DBCP.


person Kohei Nozaki    schedule 27.05.2019    source источник
comment
Как Apache DBCP, так и версия Tomcat выполняют объединение, но если промежуточный вызов метода медленный, вы также можете использовать два блока соединения.   -  person user207421    schedule 28.05.2019
comment
Ваш вариант использования довольно специфичен. Если вы знаете, что externalApiCall займет много времени, я предлагаю вам выполнить его, не открывая соединение, или вручную открывать/закрывать соединения в нужное время. Выполнение того, что вы предлагаете, приведет только к трудному для понимания коду с большим количеством волшебства, которое может нарушить ожидания людей (например, в отношении транзакционности и т. д.).   -  person Mark Rotteveel    schedule 28.05.2019
comment
Хотел бы я это сделать... как я объяснил в вопросе, к сожалению, это сложно. что касается транзакции, я ищу что-то, что может обработать это на основе setAutoCommit(false)..   -  person Kohei Nozaki    schedule 28.05.2019
comment
@KoheiNozaki Если вы ожидаете, что это будет работать с отключенной автоматической фиксацией, вы, вероятно, не найдете ничего стандартного. JDBC поддерживает только одну транзакцию на соединение, поэтому повторное использование соединения во время ожидания вашего кода просто невозможно с помощью простого JDBC (по крайней мере, без нарушения транзакционного поведения), поэтому вам нужно будет сделать что-то вне JDBC и базы данных, которые позволяют мультиплексирование нескольких транзакций в одном соединении также не очень распространено.   -  person Mark Rotteveel    schedule 28.05.2019
comment
Стандартное решение состоит в том, чтобы переместить длительную задачу за пределы обработки запроса, используя некоторую форму очереди сообщений/фонового потока. Это означает, что результаты длительной задачи не будут доступны для возврата пользователю. Готовы ли вы сделать это?   -  person guest    schedule 28.05.2019
comment
Я просто хочу, чтобы я мог это сделать..   -  person Kohei Nozaki    schedule 29.05.2019
comment
Итак, ничего не может измениться, но вы хотите другого поведения?   -  person guest    schedule 29.05.2019


Ответы (1)


Используйте пул соединений cp3.

Свойство max_idle_time может удовлетворить ваши требования здесь.

  • maxIdleTime

По умолчанию: 0

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

Для получения дополнительной информации см. https://www.mchange.com/projects/c3p0/.

person Coder    schedule 28.05.2019
comment
Разве это свойство не применяется только к соединениям в пуле? Мой вопрос касается соединений, которые получены кодом приложения и простаивают. Для меня это свойство звучит так, как будто оно не относится к приобретенным соединениям. - person Kohei Nozaki; 28.05.2019