繁体   English   中英

JDBC取消Oracle存储过程调用

[英]JDBC cancel Oracle stored procedure call

我有一个非常复杂的oracle存储过程,可以搜索和检索一些数据。 该过程返回一个输出参数 - 一个oracle游标。 我通过JDBC执行该过程:

CallableStatement stmt = conn.prepareCall("{call myprocedure(?,?,?,?}");

问题是,查询有时需要很长时间(几分钟),我希望用户能够通过单击按钮随时取消查询。 我引用了stmt对象,但不幸的是调用stmt.cancel()(来自其他线程)没有效果。

另一方面,当我将CallableStatement sql更改为某些查询时:

CallableStatement stmt = conn.prepareCall("select * from all_objects");

我在调用stmt.cancel()之后得到“java.sql.SQLTimeoutException:ORA-01013:用户请求取消当前操作” - 这就是正确的反应。

这是否意味着我不能通过jdbc取消存储过程调用,但只有简单的select语句? 有没有其他人解决过类似的问题?

我想我可以通过oracle kill session取消查询,但我使用连接池(jboss),我有足够的会话为同一个用户存在。

数据库产品版本是Oracle Database 11g企业版版本11.2.0.4.0 - 64位生产JDBC驱动程序版本是11.2.0.4.0

任何帮助将不胜感激。

该过程是只读还是写入一些数据? 尝试在db级别跟踪该会话并查看跟踪文件。 您还可以检查该特定会话的v $ undostat(使用的撤消块)。 OCIBreak调用不会回滚会话,但可能会回滚被中断的语句。

即使你杀了会话,它也不会立即死亡。 它的状态为KILLED,它会在它真正死亡之前回滚所有内容。

如果v $ undostat中的“used undo blocks”正在增加,那么会话就是“做某事”。 如果它正在减少,会话将回滚,您没有其他选择,然后等待它完成。

编辑:在OCI中,OCIBreak调用是作为带外数据包实现的。 它使用TCP标头中的特殊字段。 可以使用tcpdump轻松识别这样的数据包。 所以,即使你没有必要的权限。 在数据库端,您至少可以验证,Break数据包是否已发送到数据库。

当您100%确定中断已发送到数据库时,您必须在数据库服务器端进行调查。 我认为像“drop user cascade”这样的DDL语句不能被中断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM