线程阻塞时如何保持数据库连接

问题描述 投票:0回答:1

我集成的数据库配置为连接空闲(一段时间未使用),然后连接断开。由于我在持久配置中使用 spring batch,因此在运行的线程上始终有一个活动的数据库连接。

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

我尝试在 web 请求发生之前使用 taskscheduler 注册心跳查询(从双重中选择 1),它每 5 分钟执行一次查询以保持连接有效,但即使查询定期执行,我猜它也是在一个单独的连接,因为它在另一个线程上运行。

有人有其他建议可以在锁定线程时保持连接活动吗?

我使用 JPA 的 EntityManager 进行 haertbeat 查询

oracle jpa spring-batch database-connection spring-batch-tasklet
1个回答
1
投票

如果你使用 Spring,那么你也可以使用 HikariCP。最近的 JDBC 标准定义了方法 isValid() 所以你不必调用 SQL 来检查 Connection 是否存在。

还有一种你可以使用的机制。它被称为 TCP 保活。 如果您将节

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

默认情况下,第一个 keep alive 探测(TCP 窗口携带 0 字节)在 2 小时后发送。 而 Cisco/Juniper 通常会在一小时后切断 TCP 连接。所以通常你需要 root 权限来将 tcp_keepalive_time 的值降低到 15 分钟左右。

© www.soinside.com 2019 - 2024. All rights reserved.