Вопрос по org.apache.commons.dbcp.BasicDataSource - PullRequest
3 голосов
/ 06 ноября 2010

Я исправил некоторую ошибку, связанную с тем, как мы использовали BasicDataSource, и хотя я понимаю ее часть, у меня остались некоторые вопросы без ответа:)

Проблема: Приложение не смоглоавтоматическое подключение к базе данных после сбоя БД.

Приложение использует org.apache.commons.dbcp.BasicDataSource class в качестве пула TCP-соединений для соединения JDBC с Oracle db.

Исправление: После некоторых исследований я обнаружил, что в BasicDataSource не были установлены testOnBorrow и testOnreturn.Я предоставил запрос проверки для проверки соединений.Это устранило проблему

Максимальное количество соединений в пуле не было установлено в 1

Мое понимание: Пул соединений передаст соединение с приложением.Я думаю, что происходило то, что приложение MAGICALLY вернуло плохую коллекцию в пул при сбое базы данных.Теперь, поскольку Пул не знает, является ли это плохое соединение, он передаст то же самое соединение приложению в следующий раз, когда это потребуется, в результате чего приложение не будет автоматически повторно подключаться к БД.

Теперь, после исправления.. всякий раз, когда плохое соединение возвращается в пул соединений, оно будет отброшено и больше не будет использоваться из-за исправления, которое я сделал выше.

Теперь я знаю, что BasicDataSource оборачивает соединение перед передачей приложению, так что всякий раз, когда приложение говорит con.close ..BasicDataSource будет знать, что соединение больше не используется .. оно позаботится о любом возвратесоединение с пулом или удаление и т. д.

неотвеченный вопрос: Однако я не понимаю, что заставляет приложение ВОЛШЕБНО возвращать соединение в пул соединений, когдаон сломан [Обратите внимание, что метод con.close не вызывается, когда соединение завершается незаметно].BasicDataSource не может знать, что соединение закрыто или существует?Может ли кто-нибудь указать мне код для этого?

Я понимаю, что я понял, почему исправление сработало ??

Ответы [ 2 ]

4 голосов
/ 07 ноября 2013

Теперь я знаю, что это старая ветка, но в результатах поиска Google много, поэтому я подумал, что могу дать ей быстрый ответ.Для получения дополнительной информации о настройке BasicDataSource следует обратиться к странице конфигурации DBCP: http://commons.apache.org/proper/commons-dbcp/configuration.html

Чтобы ответить на вопрос «без ответа»: «Как BasicDataSource узнает, когда соединение установлено и должно быть возвращенопул подключений? "(перефразировано) ...

org.apache.commons.dbcp.BasicDataSource может отслеживать трафик и использование соединений, которые он предлагает, используя класс-оболочку для соединения.Каждый раз, когда вы вызываете метод для соединения или любых операторов, созданных из соединения, вы фактически вызываете класс-оболочку, который реализует интерфейс или расширяет базовый класс теми же методами (ура для полиморфизма!).Эти пользовательские методы позволяют DataSource знать, активно ли соединение.

В самом BasicDataSource есть свойство с именем removeAbandoned, а другое - с именем removeAbandonedTimeout, которое используется для настройки этого поведения возвратаПодключенные к пулу подключений.

"removeAbandoned" - логическое значение, указывающее, следует ли возвращать в пул оставленные подключения.По умолчанию установлено значение «false».

«removeAbandonedTimeout» - это целое число, представляющее число секунд бездействия, которое должно быть разрешено до того, как соединение будет считаться разорванным.Значение по умолчанию 300 (около 5 минут).

0 голосов
/ 01 февраля 2011

Глядя на тест для оставленных соединений , выясняется, что когда все соединения в пуле «используются», когда запрашивается новое соединение, «используемые» соединения проверяются на отказ (они поддерживают отметку времени последнего использованного времени).

См. BasicDataSource # setRemoveAbandoned (логическое значение) и BasicDataSource # setRemoveAbandonedTimeout (int)

Независимо отнасколько умен или нет ваш пул соединений при закрытии заброшенных соединений, вы всегда должны убедиться, что каждое соединение закрыто в блоке finally, например:

Connection conn = getConnection();
try {
    ... // perform work
} finally {
    conn.close();
}

или использовать другие средства, такие как Apache DBUtils .

...