Как отследить потерянные соединения JDBC, которые не закрыты? - PullRequest
7 голосов
/ 26 октября 2009

Мы обнаружили ошибку в старом коде, когда соединения не закрываются. Это легко исправить, но мне интересно, как мы докажем, что это исправлено. Существует выбор использования пула соединений или нет. Для использования пула было бы легко добавить мониторинг для пула, но когда пул соединений не используется, как мы отслеживаем эти незакрытые, потерянные соединения? Это как любая другая утечка памяти?

Ошибка выглядит как ошибка вырезания и вставки. У нас есть несколько классов, которые управляют подключением к БД, поэтому оно выглядит примерно так:

OurDBConn conn1 = ConnectionManager.getConnection();
try {
  // business logic
} catch () {
  //
} finally {
  ConnectionManager.returnConnection(conn1);
}

/// and then later in the same method
OurDBConn conn2 = ConnectionManager.getConnection();
try {
  // business logic
} catch () {
  //
} finally {
  ConnectionManager.returnConnection(conn1); // NOTE Error: conn1 should be conn2
}

Я не знаю, почему более ранние кодеры не просто использовали исходное соединение, а вот что это такое

(начать редактирование / добавление)

Да, у нас также есть код подключения, и поэтому я могу использовать ответы.

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

Один из вопросов, которые я должен был задать, заключается в следующем: как эти осиротевшие незамкнутые соединения проявятся в производительности системы? Кроме того, поскольку эти объекты подключения существуют только в рамках определенного метода, не будут ли подключения иметь право на сборку мусора? И затем, если они gc'ed, каков эффект gc'ed открытых соединений?

(конец редактирования)

Ответы [ 2 ]

7 голосов
/ 26 октября 2009

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

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

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

0 голосов
/ 26 октября 2009

Вы можете реализовать пользовательскую мини-среду или использовать существующую в качестве тонкой оболочки для операций JDBC. Например, есть модуль spring-jdbc ( mavenized ), который покрывает весь шаблон кода, подверженный ошибкам от разработчика.

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

...