2013-04-10 36 views
9

我是使用Oracle數據庫的Web應用程序的開發人員。但是,UI通常會觸發需要一段時間處理的數據庫操作。因此,當這些情況發生時,客戶會喜歡進度條。確定查詢的進度(Oracle PL/SQL)

我最近發現我可以從第二個連接查詢V $ SESSION_LONGOPS,這很好,但它只適用於需要6秒以上的操作。這意味着我無法更新UI中的進度條,直到6秒過去。

我已經研究了V $ SESSION中的等待時間,但據我所見,這不包括等待查詢。

有沒有辦法獲得當前正在運行的會話查詢的進度?或者我應該隱藏進度條直到6秒過去?

+3

如果您有100 x 1秒的操作。他們都不會出現在SESSION_LONGOPS中。如果你有兩個連續十秒的操作,在你的第一個命中100%之後,第二個將從0%開始。這將是一個令人沮喪的進度條。我認爲這是需要捻轉圈的事情之一,而不是狀態欄,因爲你只是不知道需要多長時間。 – 2013-04-10 23:41:45

回答

1

我已經做了很多Web開發與Oracle多年來,發現大多數用戶喜歡不確定的進度條,比一個確定的酒吧,是不準確的(一拉漂亮的Microsoft's進度條多其中任何煩我沒有結束),不幸的是,沒有準確確定查詢進度的可靠方法。

雖然你對長操作能力的研究是令人欽佩的,並且肯定有助於使數據庫查詢的進度更加可靠,但它不能考慮其他可能影響Web操作事務性的變量進度(網絡負載,數據庫負載,應用程序服務器負載,客戶端數據解析,用戶點擊提交按鈕1000次等等)。

我會堅持使用JavaScript回調不確定的進度方法。實施起來要容易得多,並且會適當地管理用戶的期望。

8

這些操作是Pl/SQL調用還是隻是長期運行的SQL?

通過PL/SQL操作,我們可以在DBMS_APPLICATION_INFO包中寫入SET_SESSION_LONGOPS()的消息。我們可以在V$SESSION_LONGOPS中監控這些消息。 Find out more

爲此,您需要能夠以工作單位量化操作。這些必須是具體的東西,數字而不是時間的迭代。所以如果操作插入10000行,你可以將它分成10批。 totalwork參數是批次數(即10),並且在每1000行後調用SET_SESSION_LONGOPS()以增加參數sofar。這將允許您渲染十個塊的溫度計。

這些消息是基於會話的,但是沒有自動的方式將當前消息與來自同一個會話的以前的消息區分開SID。但是,如果您將UID分配給context參數,則可以使用該值過濾視圖。


這不適用於單個長時間運行的查詢,因爲我們沒有辦法將它分成塊。

+0

感謝您的回覆。對於大多數操作,我將堅持使用旋轉進度條,但對於需要很長時間查詢(需要幾分鐘才能運行的查詢)的問題,我正考慮記錄上次查詢運行的時間,並使用它來估計進度條。 即使它稍微關閉,當您等待幾分鐘的動作發生時,進度條至少會給用戶一些希望發生某些事情比盲目發生。 – 2013-04-11 15:53:54

2

我發現這非常有用

dbms_session.set_module("MY Program" , "Kicking off ... ") 
.. 
dbms_session.set_action("Extracting data ... ") 
.. 
dbms_session.set_action("Transforming data ... ") 
.. 

您可以監視使用

select module , action from v$session where sid = :yoursessionid 
0

使用V $ _SESSION_LONGOPS的進展,需要設置TIMED_STATISTICS = true或SQL_TRACE = TRUE。您的數據庫模式必須被授予ALTER SESSION系統特權才能這樣做。

我曾嘗試使用V $ _SESSION_LONGOPS處理複雜和長時間運行的查詢。但是,它發現V $ _SESSION_LONGOPS可能會顯示像全表掃描,聯合操作等查詢的部分的進度。

參見:http://www.dba-oracle.com/t_v_dollar_session_longops.htm

你可以做的就是向用戶顯示「查詢仍在運行」。我實現了嵌入到<TD>中的<DIV>,該瀏覽器發送的每個狀態請求都會變得更長。狀態請求由window.SetTimeout(每3秒)發起,並且是對服務器端過程的AJAX調用。服務器端程序返回的狀態報告只是說「我們仍在運行」。進度條的寬度(即<DIV>的寬度)每次增加5%,並在顯示100%後重置爲5%。

對於長時間運行的查詢,您可能會跟蹤他們在單獨的表中所佔用的時間,可能會用單個條目來改變where子句。您可以使用它來顯示平均時間加上客戶端對話框中剛過去的時間。

如果你有一個長期運行的PL/SQL程序或服務器端做的幾個步驟等等,試試這個:

  • 創建狀態消息表
  • 使用唯一密鑰的任何進程用戶啓動。建議:客戶端的JavaScript日期以毫秒爲單位+會話ID。
  • 的情況下長時間運行的程序是在瀏覽器窗口中的鏈接來啓動,使用DBMS_JOB.SUBMIT運行的程序,而不是直接運行
  • 寫更新狀態表一小段程序的程序創建一個作業,使用PRAGMA AUTONOMOUS_TRANSACTION。該編譯指示允許您在不提交主程序更新的情況下提交狀態表的更新。主程序的每個主要步驟都應該在此狀態表中有一個自己的輸入。
  • 寫了一個程序來查詢狀態表由瀏覽器被稱爲
  • 寫一個由AJAX調用,如果使用點擊「取消」或關閉窗口
  • 寫了一個程序被稱爲調用的過程通過完成每個步驟後的主要過程:如果設置了取消標誌或者瀏覽器未查詢狀態(例如60秒),則查詢狀態表,並以20000s內的數字引發異常。在主過程的異常處理程序中查找此錯誤,執行回滾並更新狀態表。