ora-01013 是客户端主动中断信号,主因是超时配置与存储过程耗时不匹配;须关闭odbc的enable query timeout、显式设置commandtimeout、禁用dbms_output、用dbms_application_info定位阻塞点,并逐层排查多层超时叠加。

ORA-01013 不是数据库错误,而是客户端主动中断信号;根本原因几乎总是超时配置与存储过程实际耗时不匹配,而非 PL/SQL 逻辑缺陷。
ODBC 数据源的 Enable Query Timeout 必须关闭
这是 Windows 平台下最常被忽略的硬性拦截点。只要在 ODBC 数据源管理器中勾选了 Enable Query Timeout,默认 60 秒一到,驱动就向 Oracle 发送中断请求,触发 ORA-01013 —— 即使你的存储过程本身完全健康。
- 操作路径:运行
odbcad32.exe(32 位应用用C:\Windows\SysWOW64\odbcad32.exe),选中对应 Oracle DSN →Configure→Advanced→ 取消勾选Enable Query Timeout - 或更直接:在连接字符串末尾加
;QTO=F - 改完后必须重启调用该 DSN 的 .NET 进程(如 IIS 应用池、WinForms 主程序),否则旧连接缓存仍生效
SqlCommand.CommandTimeout 和 Oracle JDBC 行为不等价
.NET 中设置 SqlCommand.CommandTimeout 是有效的,但它只作用于当前命令执行周期;而 Oracle 驱动(如 Oracle.ManagedDataAccess)内部还受底层网络超时控制,且 CommandTimeout=0 在 ODP.NET 中表示“使用连接字符串默认值”,不是真正禁用。
- 显式设为较大值(如
command.CommandTimeout = 300)比设 0 更可靠 - 若用连接池,确保连接字符串里没隐式覆盖超时,例如避免混用
Connection Timeout=15(这是建连超时,和执行无关) - 注意:此超时对存储过程中用
EXECUTE IMMEDIATE动态执行的 SQL 无效,只约束外层ExecuteNonQuery()调用
存储过程内隐式阻塞点要主动暴露
ORA-01013 常掩盖真实瓶颈。比如你看到“删了 10 秒才报错”,实际可能是锁等待、全表扫描或 DBMS_OUTPUT 大量刷屏拖慢响应,但客户端只感知为“超时”。这时不能只调大 timeout,得让过程自己“说话”。
- 在关键步骤前加
DBMS_APPLICATION_INFO.SET_MODULE('PKG_NAME', 'STEP_1');,便于从v$session实时查卡在哪 - 禁用
DBMS_OUTPUT.ENABLE(尤其生产环境),大量PUT_LINE会显著拉长执行时间 - 检查是否有未提交事务占住行锁:用
SELECT blocking_session, event FROM v$session WHERE sid = SYS_CONTEXT('USERENV','SID')确认是否真在等资源
Spring Boot + HikariCP 场景下 timeout 设置易混淆
很多人以为配了 spring.datasource.hikari.connection-timeout=0 就能解决 ORA-01013,其实它只控制从连接池获取连接的等待时间,对存储过程执行毫秒级超时毫无影响。
- 真正起作用的是语句级 timeout:在
OracleCommand或CallableStatement上调用CommandTimeout/setQueryTimeout() - HikariCP 不拦截或重写这个值,但某些 AOP 拦截器(如自定义 SQL 日志切面)可能意外重置它
- 验证方式:在抛出 ORA-01013 前,查
v$sqlarea中对应 SQL 的elapsed_time,若远小于客户端 timeout 值,说明中断来自中间层而非 Oracle
真正难处理的从来不是 timeout 数值本身,而是当多个超时层叠(ODBC + .NET Command + 应用容器事务超时 + 存储过程内锁等待)时,错误日志只显示 ORA-01013,却无法定位哪一层先动手——必须逐层关掉非必要超时,并用 v$session 和 DBMS_APPLICATION_INFO 把执行流钉死到具体语句。











