Image

Imagejdevelop wrote in Imageru_java

Categories:

Автозакрытие соединений в JDBC

Привет, уважаемые сообщники. Рискуя напороться на непонимание, все же задам вопрос:

есть очень legacy приложение, которое писалось странно. В этом приложении широко используются Connection, разнообразные PreparedStatement и прочие ResultSet. Соответственно их нужно закрывать, дабы не случалось висячих хендлов. Это по старинке делается таким себе boilerplate-code, вида

Connection dbh = null;

try {
    dbh = dataSource.getConnection();
    .....
} finally {
    if (dbh != null)
        dbh.close();
}


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

Вопрос - как бы с наименьшими затратами и модификацией этого кода выправить ситуацию?

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

Но вдруг есть и более прямые пути? В частности, когда я разбирал ACE/TAO, там была концепция саморазрушающихся объектов, когда выполнение выходило за текущую видимость. В Java это по всей видимости метод finalize, но насколько я понял, GC не гарантирует вызов этого метода.