ORA-01013是客户端主动取消操作的提示,非数据库自身错误;主因包括ODBC启用查询超时、JDBC设置setQueryTimeout、锁等待或应用层中断,需同步检查客户端配置、连接池、存储过程事务及锁状态。
ORA-01013 是客户端主动中断,不是数据库报错
这个错误本质是 Oracle 客户端(比如 ODBC、JDBC、PL/SQL Developer)在等待 SQL 执行返回时,因超时或用户手动点击「取消」而向服务端发送了中断请求,服务端响应为 ORA-01013。它不表示存储过程本身语法或逻辑出错,而是执行环境切断了连接。
常见触发场景包括:
- 存储过程里有隐式长耗时操作(如未加索引的游标循环、
DBMS_OUTPUT.PUT_LINE大量输出、嵌套远程查询) - 调用方设置了硬性超时(如 JDBC 的
Statement.setQueryTimeout(30)) - ODBC 数据源勾选了
Enable Query Timeout - Web 应用容器(如 WebLogic)对事务设了全局超时(如 JTA Transaction Timeout = 30s),而存储过程内事务未及时提交
ODBC 连接下必须关掉 Enable Query Timeout
这是最常被忽略的配置点。即使你的存储过程逻辑没问题,只要 Windows ODBC 数据源管理器里该选项处于勾选状态,任何执行超过默认 60 秒的存储过程都会触发 ORA-01013。
操作路径:
- 打开
odbcad32.exe(64 位系统用C:\Windows\SysWOW64\odbcad32.exe配 32 位驱动) - 选择对应 Oracle DSN → Configure → Advanced → 取消勾选
Enable Query Timeout - 或直接在连接字符串末尾加
;QTO=F
注意:改完后必须重启调用该 DSN 的应用程序(比如 Excel、Power BI、旧版 VB 程序),否则缓存的连接设置不会刷新。
JDBC 调用存储过程时 queryTimeout 设为 0 不等于无限制
CallableStatement.setQueryTimeout(0) 表示“使用驱动默认超时”,而非真正禁用。Oracle JDBC 驱动(ojdbc8.jar)默认仍是 0(即无限),但某些中间件(如 Druid、WebSphere)会覆盖此行为。
更稳妥的做法是:
- 在连接 URL 中显式指定:
jdbc:oracle:thin:@host:1521/orcl?oracle.jdbc.ReadTimeout=0&oracle.jdbc.SocketTimeout=0 - 如果用 Spring Boot,配置
spring.datasource.hikari.connection-timeout=0(仅控制连接获取,不影响语句执行) - 真正要禁用语句级超时,得在
CallableStatement上调用setQueryTimeout(0),且确保没被 Connection Pool 拦截重写
另外注意:setQueryTimeout() 对 EXECUTE IMMEDIATE 内部的动态 SQL 无效,只作用于当前 CallableStatement 的 execute 调用。
存储过程内部锁等待导致的假性超时
很多情况下,ORA-01013 是表锁或行锁卡住引发的连锁反应。比如存储过程中执行了 SELECT ... FOR UPDATE,但上游事务没提交,后续调用就一直阻塞,直到客户端超时抛出该错误。
排查方法:
- 查
v$session_blockers或运行SELECT blocking_session, sid, serial#, event FROM v$session WHERE blocking_session IS NOT NULL; - 检查存储过程中是否遗漏
COMMIT或ROLLBACK,尤其在异常分支里 - 避免在存储过程中做跨事务的长时间操作(如发邮件、调外部 HTTP),应拆到应用层处理
一个容易被绕过的细节:PL/SQL 匿名块里调用存储过程,如果匿名块本身没设超时,但调用链中某处用了 DBMS_ALERT.WAITONE 或 DBMS_LOCK.SLEEP,也会让外部客户端误判为“卡死”。
超时问题从来不是单点配置能解决的,它横跨客户端设置、连接池策略、存储过程事务边界和数据库锁状态 —— 少一环都可能让 ORA-01013 在你以为已修复的地方突然复现。











