Почему запросы в JDBI закрываются?

#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 на этом и закрыл запросы.

Закрытие соединения должно очистить все связанные курсоры для вас, но было бы лучше отпустить их, как только вы закончите с ними, потому что это позволяет серверу базы данных работать более эффективно.