Spring Boot连接Oracle失败重试后自动关停的实现方法
Spring Boot连接Oracle失败重试+自动关停实现方案
方案1:基于内置连接池配置实现(零额外代码)
Spring Boot默认集成的HikariJDBC连接池本身就带启动连接失败重试能力,直接改配置文件就能满足需求,不需要写自定义逻辑:
spring: datasource: url: jdbc:oracle:thin:@//你的Oracle实例IP:1521/服务名 username: 数据库账号 password: 数据库密码 driver-class-name: oracle.jdbc.OracleDriver hikari: # 连接获取超时时间,单次尝试连接超过这个时间就判定失败,单位毫秒 connection-timeout: 1000 # 初始化连接池总超时时间,按每次重试间隔1秒、重试3次配置为3000即可 initialization-fail-timeout: 3000 sql: init: # 如果你开启了Spring Boot自动执行初始化SQL脚本的功能,把脚本执行重试次数设为3 max-retries: 3 continue-on-error: false
配置生效后,HikariCP启动时会持续尝试建立数据库连接,累计超时后会直接抛出启动异常,Spring Boot遇到这类启动致命错误会自动终止应用进程,不需要额外写关停逻辑。
方案2:自定义启动校验逻辑(重试规则完全可控)
如果要精准控制重试次数、重试间隔,不想依赖连接池的超时凑逻辑,可以自定义启动执行器,在应用正式对外服务前做连接校验:
import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.stereotype.Component; import java.sql.Connection; @Slf4j @Component @RequiredArgsConstructor public class DbConnectionRetryValidator implements ApplicationRunner { // 按需配置最大重试次数,这里设为3 private static final int MAX_RETRY_COUNT = 3; // 每次重试间隔,单位毫秒,这里设为2秒 private static final long RETRY_WAIT_MILLIS = 2000; private final ConfigurableApplicationContext applicationContext; private final javax.sql.DataSource dataSource; @Override public void run(ApplicationArguments args) throws Exception { boolean connected = false; for (int i = 1; i <= MAX_RETRY_COUNT; i++) { try (Connection connection = dataSource.getConnection()) { if (connection.isValid(3)) { log.info("第{}次尝试连接Oracle数据库成功", i); connected = true; break; } } catch (Exception e) { log.warn("第{}次尝试连接Oracle数据库失败:{}", i, e.getMessage()); if (i < MAX_RETRY_COUNT) { Thread.sleep(RETRY_WAIT_MILLIS); } } } if (!connected) { log.error("累计{}次连接Oracle均失败,应用即将退出", MAX_RETRY_COUNT); // 触发Spring容器正常关停,返回状态码1标识异常退出 System.exit(SpringApplication.exit(applicationContext, () -> 1)); } } }
这个逻辑会在所有Spring Bean初始化完成后、应用开始接收请求前执行,完全按照你设定的重试规则走,不会出现应用启动成功但数据库不可用的问题。
注意事项
- 两种方案对MyBatis、JPA等上层ORM框架无侵入,不需要额外调整框架配置。
- 重试次数建议设为2-3次即可,足够覆盖数据库临时闪断、网络瞬时抖动的场景,重试间隔设1-3秒为宜,避免应用启动阻塞太久。
- 以上逻辑仅覆盖应用启动阶段的连接校验,应用运行过程中出现数据库断连的场景,需要靠连接池自身的心跳检测、断连重连能力处理,和启动阶段的重试逻辑不冲突。
内容的提问来源于stack exchange,提问作者Himanshu Gupta
相关产品推荐
相关产品推荐

