spring boot无法自动处理oracle密码过期——ora-28001/28002发生在连接建立阶段,hikaricp等配置无效;必须通过alter profile ... password_life_time unlimited禁用策略,并对已过期用户执行alter user ... identified by显式重置。

Spring Boot 本身不提供 Oracle 密码过期的“自动重连”能力——ORA-28001(密码已过期)或 ORA-28002(密码即将过期)是数据库服务端主动抛出的认证级错误,连接池在建立新连接时就会失败,不会进入“重试-重连”流程。真正要解决的,是避免密码过期导致连接中断,而不是让 HikariCP 或 Spring 自动续命。
Oracle 密码过期错误发生在连接建立阶段
当 HikariCP 尝试从连接池获取连接(或验证空闲连接)时,Oracle 服务端会在 jdbc:oracle:thin 认证握手环节直接拒绝,抛出 ORA-28001 或 ORA-28002。此时连接尚未建立成功,HikariCP 的 connection-test-query、validation-timeout、keepalive-time 等配置全部无效。
- ORA-28001:密码已过期 → 应用无法建连,所有请求立即失败
- ORA-28002:密码将在 N 天后过期 → 连接可建,但 JDBC 驱动会记录警告(部分日志级别下可见),不影响当前连接,但不解决到期后中断问题
必须从 Oracle 侧禁用密码生命周期策略
唯一可靠方案是修改 Oracle 用户所属 PROFILE 的 PASSWORD_LIFE_TIME,使其不再触发过期机制。Spring Boot 配置里任何“重连参数”都绕不开这个前提。
- 先确认用户绑定的 profile:
SELECT username, profile FROM dba_users WHERE username = 'YOUR_USER'; - 查当前策略:
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'YOUR_PROFILE' AND resource_name = 'PASSWORD_LIFE_TIME'; - 执行 DBA 权限命令(如
sqlplus / as sysdba):ALTER PROFILE YOUR_PROFILE LIMIT PASSWORD_LIFE_TIME UNLIMITED; - ⚠️ 注意:该操作对新密码立即生效,但**不会刷新已有用户的
EXPIRY_DATE字段**;若用户已过期,仍需ALTER USER xxx IDENTIFIED BY ...或IDENTIFIED BY VALUES '...'显式重置
Spring Boot 中不能依赖“自动重连”来掩盖密码过期
有人尝试用 HikariCP 的 connection-init-sql 执行 ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS' 类语句,或加 spring.datasource.hikari.connection-timeout=30000 延长等待——这些对 ORA-28001 完全无效。只要密码过期,getConnection() 调用就会抛异常,根本走不到初始化 SQL 阶段。
- 不要在
application.yml里配spring.datasource.hikari.data-source-properties.oracle.jdbc.autoCommitSpecCompliant=false之类试图“绕过”的参数——它和密码过期无关 - 加密存储
db.password(如用jasypt-spring-boot-starter)只解决密钥安全问题,不改变 Oracle 认证逻辑 - 如果应用必须使用定期轮换密码的策略,那需要配套运维流程:提前通知、更新加密配置、滚动重启,而非指望连接池自动适配
最常被忽略的一点:改完 PASSWORD_LIFE_TIME UNLIMITED 后,一定要查 dba_users 里的 expiry_date 是否为 NULL 或远期时间。否则你以为策略生效了,其实老用户的倒计时还在跑。











