簡體   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