0

我集成的数据库配置为好像连接处于空闲状态(一段时间未使用),然后连接被丢弃。由于我在持久配置中使用弹簧批处理,因此在运行线程上总是有一个活动的数据库连接。

我的一项春季批处理作业依赖于来自外部 Web 服务的数据,这需要很长时间才能执行。这就是为什么当我得到结果时我已经失去了数据库连接。

我尝试在 Web 请求发生之前使用 taskscheduler 注册一个心跳查询(从 dual 中选择 1),它每 5 分钟执行一次查询以保持连接处于活动状态,但即使查询定期执行,我猜它也会单独执行查询连接,因为它在另一个线程上运行。

有没有人有其他建议可以在锁定线程时保持连接处于活动状态?

我使用 JPA 的 EntityManager 进行 haertbeat 查询

4

1 回答 1

0

如果你使用 Spring,那么你也使用 HikariCP。最近的 JDBC 标准定义了方法 isValid(),因此您不必调用 SQL 来检查 Connection 是否处于活动状态。

此外,您还可以使用另一种机制。它被称为 TCP keepalive。如果将节ENABLE=BROKEN插入 JDBC url,Oracle JDBC 驱动程序将在 TCP 连接上启用 TCP Keepalive 功能

jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=myhost))(CONNECT_DATA=(SERVICE_NAME=orcl)))

然后,即使您的线程被阻塞,Linux 内核也会通过 TCP 连接发送 keepalive 探测。

注意:第一次探测的延迟和频率由 Linux 内核参数决定。

# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75

# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

默认情况下,第一个保持活动探测(TCP 窗口携带 0 字节)在 2 小时后发送。而 Cisco/Juniper 通常会在一小时后切断 TCP 连接。

于 2020-07-28T11:50:05.193 回答