#java #jdbi
#java #jdbi
Вопрос:
У меня есть Java-приложение, которое использует JDBI для моего кода базы данных. У меня есть много DAO, которые используют примерно следующую конструкцию для запросов:
return handle.createQuery(sql)
.bind("variable", variable)
.mapToBean(Bean.class)
.list();
Где handle
находится Handle
объект JDBI. Я закрываю дескриптор в другом месте приложения в конце транзакции.
Я отсканировал свой код с помощью SonarQube, и он жалуется, что я открываю Query
объекты JDBI, которые реализуют AutoCloseable
, не закрывая их. SonarQube предлагает закрыть их при попытке с использованием ресурсов, например:
try(Query query = handle.createQuery(sql)){
return query.bind("variable", variable)
.mapToBean(Bean.class)
.list();
}
Я обеспокоен тем, что это может закрыть базовый дескриптор или другие ресурсы, которые мне нужны для других запросов, происходящих внутри транзакции. Я также скептически отношусь к тому, что их нужно закрывать. Почему JDBI делает эти объекты запросов закрываемыми? Я ничего не нашел в документации, указывающей, какие ресурсы они открывают. Правильно ли работает SonarQube или это можно безопасно игнорировать?
Спасибо.
Комментарии:
1. Я не знаю, помогает ли это, но вот источник, где его вызов clean: github.com/jdbi/jdbi/blob/… Пока ничего не добавляется
cleanable
, тогда должно быть хорошо, чтобы это было вtry-with-resource
2. В случае, если это поможет: дескрипторы могут использоваться в обратных вызовах, и в этом случае они автоматически закрываются при завершении обратного вызова. Вот как я обычно с ними справляюсь (каламбур сожалею).
3. Да, я знаю о методе обратного вызова — это очень приятно — но, к сожалению, из-за того, что приложение должно быть структурировано для работы с используемой мной платформой, этот метод на самом деле неосуществим.
Ответ №1:
Запрос JDBI представляет собой оболочку вокруг оператора JDBC и результирующего набора, где результирующий набор, в свою очередь, оборачивает курсор базы данных. Закрытие запроса закрывает оператор и результирующий набор, который освобождает курсор, освобождая ресурсы базы данных. Существует ограничение на количество одновременно открытых курсоров в базе данных. Закрытие запроса не приведет к закрытию соединения с базой данных.
Я был бы удивлен, если бы Sonarqube знал что-нибудь конкретное о JDBI, кажется вероятным, что он просто следует правилу, в котором говорится, что все автоматически закрываемое должно быть закрыто. Тем не менее, это неплохое правило для большинства вещей. Я бы послушал Sonarqube на этом и закрыл запросы.
Закрытие соединения должно очистить все связанные курсоры для вас, но было бы лучше отпустить их, как только вы закончите с ними, потому что это позволяет серверу базы данных работать более эффективно.