Заставить Hikari / Hibernate закрыть устаревшие (утечка?) Соединения - PullRequest
0 голосов
/ 20 сентября 2018

Я работаю с источником данных FileMaker 16 через официальный драйвер JDBC в Spring Boot 2 с Hibernate 5.3 и Hikari 2.7.

Производительность сервера FileMaker низкая, для больших таблиц время выполнения SQL-запроса может достигать минуты.Иногда это приводит к утечке соединения, когда пул соединений полон активных соединений, которые никогда не освобождаются.

Вопрос состоит в том, как заставить активные соединения в пуле, которые висят там, сказать, что они закрываются в течение двух минут,переводя их в режим ожидания и делая доступными для использования снова.

Например, я обращаюсь к источнику данных FileMaker через RestController, используя метод findAll в org.springframework.data.repository.PagingAndSortingRepository:

@RestController
public class PatientController {

    @Autowired
    private PatientRepository repository;

    @GetMapping("/patients")
    public Page<Patient> find(Pageable pageable) {
        return repository.findAll(pageable);
    }
}

Вызов /patients несколько раз в сыром виде приводит к утечке соединения, вот что сообщает Хикари:

2018-09-20 13: 49: 00.939 ОТЛАДКА 1 --- [экономка l-1]com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - Статистика пула (всего = 10, активно = 10, бездействует = 0, ожидание = 2)

Также выдает такие исключения:

java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) ~[HikariCP-2.7.9.jar!/:na]

Что мне нужно, если repository.findAll занимает больше N секунд, соединение должно быть разорвано, а метод контроллера должен выдать исключение.Как этого добиться?

Вот мой конфиг Hikari:

 allowPoolSuspension.............false
 autoCommit......................true
 catalog.........................none
 connectionInitSql...............none
 connectionTestQuery............."SELECT COUNT(*) FROM Clinics"
 connectionTimeout...............30000
 dataSource......................none
 dataSourceClassName.............none
 dataSourceJNDI..................none
 dataSourceProperties............{password=<masked>}
 driverClassName................."com.filemaker.jdbc.Driver"
 healthCheckProperties...........{}
 healthCheckRegistry.............none
 idleTimeout.....................600000
 initializationFailFast..........true
 initializationFailTimeout.......1
 isolateInternalQueries..........false
 jdbc4ConnectionTest.............false
 jdbcUrl.........................jdbc:filemaker://***:2399/ec_data
 leakDetectionThreshold..........90000
 maxLifetime.....................1800000
 maximumPoolSize.................10
 metricRegistry..................none
 metricsTrackerFactory...........none
 minimumIdle.....................10
 password........................<masked>
 poolName........................"HikariPool-1"
 readOnly........................false
 registerMbeans..................false
 scheduledExecutor...............none
 scheduledExecutorService........internal
 schema..........................none
 threadFactory...................internal
 transactionIsolation............default
 username........................"CHC"
 validationTimeout...............5000

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Драйвер JDBC filemaker игнорирует параметр javax.persistence.query.timeout, даже если значение времени ожидания установлено в реализации драйвера для установщика java.sql.setQueryTimeout.Поэтому я решил проблему, расширив класс com.filemaker.jdbc.Driver и переопределив метод connect, чтобы он добавил параметр sockettimeout в свойства соединения.При наличии этого параметра драйвер FM JDBC прерывает соединение, если данные не поступали из сокета в течение периода ожидания.

Я также подал проблему с filemaker: https://community.filemaker.com/message/798471

0 голосов
/ 21 сентября 2018

HikariCP фокусируется только на управлении пулом соединений для управления соединениями, которые он из него сформировал.

loginTimeout - сколько времени HikariCP будет ожидать установления соединения с базой данных (в основном, соединение JDBC)

spring.datasource.hikari.connectionTimeout=30000

maxLifetime - как долго будет жить соединениепул перед закрытием

spring.datasource.hikari.maxLifetime=1800000

idleTimeout - как долго неиспользуемое соединение живет в пуле

spring.datasource.hikari.idleTimeout=30000

Используйте javax.persistence.query.timeout, чтобы отменить запрос, если онзанимает больше времени, чем определенное время ожидания.

javax.persistence.query.timeout (Long - миллисекунды)

Подсказка javax.persistence.query.timeout определяет, какдолго запрос может быть запущен, прежде чем он будет отменен.Hibernate сам не обрабатывает этот тайм-аут, но предоставляет его драйверу JDBC с помощью метода JDBC Statement.setTimeout.

...