我正在通过带有Hibernate 5.3和Hikari 2.7的Spring Boot 2中的官方JDBC驱动程序使用FileMaker 16数据源。
FileMaker 服务器性能较差,对于大型表,SQL 查询执行时间可能达到一分钟。有时,当连接池充满永远不会释放的活动连接时,它会导致连接泄漏。
问题是如何强制池中的活动连接已经挂在那里两分钟,将它们移动到空闲状态并可供再次使用。
例如,我使用org.springframework.data.repository.PagingAndSortingRepository
中的findAll
方法通过 RestController 访问 FileMaker 数据源:
@RestController
public class PatientController {
@Autowired
private PatientRepository repository;
@GetMapping("/patients")
public Page<Patient> find(Pageable pageable) {
return repository.findAll(pageable);
}
}
在原始中调用/patients
几次会导致连接泄漏,以下是 Hikari 报告的内容:
2018-09-20 13:49:00.939 调试 1 --- [L-1 管家] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (总计 = 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 秒,则必须终止连接,并且控制器方法必须抛出并异常。如何实现?
这是我的光配置:
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
> 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 – milliseconds(
javax.persistence.query.timeout 提示定义了查询的长度 允许在取消之前运行。Hibernate不处理这个 超时本身,但通过 JDBC 将其提供给 JDBC 驱动程序 Statement.setTimeout 方法。
文件生成器 JDBC 驱动程序忽略javax.persistence.query.timeout
参数,即使超时值是在驱动程序的java.sql.setQueryTimeout
setter 实现中设置的。因此,我通过扩展类com.filemaker.jdbc.Driver
并重写connect
方法解决了该问题,以便它将sockettimeout
参数添加到连接属性中。有了这个参数,如果在超时期限内没有数据来自套接字,FM JDBC 驱动程序将中断连接。
我还向文件制作者提出了一个问题:https://community.filemaker.com/message/798471