2013-04-10 9 views
9

Jestem programistą w aplikacji internetowej, która korzysta z bazy danych Oracle. Jednak często interfejs użytkownika uruchamia operacje na bazie danych, których przetworzenie zajmuje trochę czasu. W rezultacie klient chce pasek postępu, gdy wystąpią takie sytuacje.Określanie postępu zapytania (Oracle PL/SQL)

Niedawno odkryłem, że mogę wysłać zapytanie V $ SESSION_LONGOPS z drugiego połączenia, a to jest świetne, ale działa tylko w przypadku operacji, które trwają dłużej niż 6 sekund. Oznacza to, że nie mogę zaktualizować paska postępu w interfejsie użytkownika, dopóki nie minie 6 sekund.

Zrobiłem badania czasu oczekiwania w V $ SESSION, ale o ile widziałem, to nie obejmuje oczekiwania na kwerendę.

Czy istnieje sposób na uzyskanie postępu aktualnie uruchomionego zapytania dotyczącego sesji? A może powinienem ukrywać pasek postępu, aż minie 6 sekund?

+3

Jeśli masz 100 x 1 sekundę operacji. Żadne z nich nie pojawi się w SESSION_LONGOPS. Jeśli masz 2 sekwencyjne dziesięć sekund operacji, po pierwszym trafieniu 100%, drugi zaczyna się od 0%. To byłby frustrujący pasek postępu.Myślę, że jest to jedna z tych rzeczy, które wymagają kręcenia się, a nie paska stanu, ponieważ po prostu nie wiesz, jak długo to potrwa. –

Odpowiedz

1

Zrobiłem sporo tworzenie stron internetowych z Oracle na przestrzeni lat i okazało się, że większość użytkowników preferuje nieokreślony pasek postępu, niż barze zdeterminowanej że jest niedokładny (a la prawie każdy z Microsoft's paski postępu, które mnie wkurza bez końca) i niestety nie ma nieomylnego sposobu dokładnego określenia postępu zapytania.

Podczas gdy badanie długoterminowych możliwości jest godne podziwu i zdecydowanie pomogłoby uczynić postęp kwerendy bazodanowej bardziej wiarygodnym, nie może brać pod uwagę mnóstwa innych zmiennych, które mogą/będą wpływać na transakcję sieciową. postęp (obciążenie sieci, obciążenie bazy danych, obciążenie serwera aplikacji, przetwarzanie danych po stronie klienta, kliknięcie przycisku przesyłania 1000 razy, itd.).

Trzymałbym się metody nieokreślonego postępu przy użyciu wywołań JavaScript. Jest o wiele łatwiejsze do wdrożenia i będzie odpowiednio zarządzać oczekiwaniami użytkownika.

8

Czy te operacje wywołują połączenia Pl/SQL lub po prostu długotrwałe SQL?

Dzięki operacjom PL/SQL możemy pisać wiadomości z SET_SESSION_LONGOPS() w pakiecie DBMS_APPLICATION_INFO. Możemy monitorować te wiadomości w V$SESSION_LONGOPS. Find out more.

Aby to zadziałało, musisz mieć możliwość ilościowego określenia operacji w jednostkach pracy. Muszą to być iteracje czegoś konkretnego, a numeryczne nie czas. Więc jeśli operacja jest wstawić 10000 wierszy można podzielić to na 10 partii. Parametr totalwork to liczba partii (tj. 10) i wywołujesz SET_SESSION_LONGOPS() po każdych 1000 wierszy, aby zwiększyć parametr sofar. To pozwoli ci wyrenderować termometr z dziesięciu bloków.

Wiadomości te są oparte na sesjach, ale nie ma automatycznego sposobu rozróżniania bieżącej wiadomości od poprzedniej wiadomości od tej samej sesji. SID: &. Jednak jeśli przypiszesz UID do parametru context, możesz użyć tej wartości do filtrowania widoku.


Nie zadziała w przypadku pojedynczego długiego zapytania, ponieważ nie ma sposobu, aby podzielić go na porcje.

+0

Dziękuję za wszystkie odpowiedzi. Mam zamiar trzymać się paska postępu dla większości operacji, ale w przypadku bardzo długich zapytań (trwających kilka minut), myślę o zapisaniu czasu, w którym ostatnie zapytanie trwało, i zastosowaniu tego do oszacowania pasek postępu. Nawet jeśli jest lekko wyłączony, gdy czeka się kilka minut na działanie, pasek postępu przynajmniej daje użytkownikowi pewną nadzieję, że coś się dzieje, nie zaślepienie. –

2

Znalazłem to bardzo przydatne

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

można monitorować postępy za pomocą

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

Korzystanie V $ _SESSION_LONGOPS wymaga, aby ustawić TIMED_STATISTICS = true lub SQL_TRACE = true. Twój schemat bazy danych musi mieć uprawnienie systemowe ZMIENIAJ SESJĘ, aby to zrobić.

Kiedyś próbowałem używać V $ _SESSION_LONGOPS ze złożonym i długotrwałym zapytaniem. Ale okazało się, że V $ _SESSION_LONGOPS może pokazać postęp części zapytania, takie jak pełne skanowanie tabel, operacje łączenia i tym podobne.

Zobacz także: http://www.dba-oracle.com/t_v_dollar_session_longops.htm

Co można zrobić, to po prostu pokazać użytkownikowi „kwerenda nadal działa”. Zaimplementowałem <DIV> zagnieżdżony w <TD>, który jest dłuższy z każdym żądaniem statusu wysłanym przez przeglądarkę. Żądania statusu są inicjowane przez window.SetTimeout (co 3 sekundy) i są wywołaniami AJAX do procedury po stronie serwera. Raport o stanie zwrócony przez procedurę po stronie serwera mówi po prostu "wciąż działamy". Szerokość paska postępu (tj. <DIV>) zwiększa się o 5% szerokości o <TD> s i jest resetowana do 5% po wyświetleniu 100%.

W przypadku długotrwałych zapytań można śledzić czas, jaki zajęły w oddzielnej tabeli, ewentualnie z indywidualnymi wpisami dotyczącymi różnych klauzul where. Możesz użyć tego do wyświetlenia średniego czasu oraz czasu, który upłynął w oknie dialogowym po stronie klienta.

Jeśli masz długi bieg PL procedurę/SQL lub podobnego po stronie serwera robi kilka kroków, spróbuj tego:

  • utworzyć tabelę komunikatów statusowych
  • użyciu unikatowego klucza dla każdego procesu użytkownik zaczyna. Sugestia: data javascript po stronie klienta w milisekundach + identyfikator sesji.
  • w przypadku, gdy długotrwała procedura ma zostać uruchomiona przez łącze w oknie przeglądarki, utwórz zadanie za pomocą DBMS_JOB.SUBMIT, aby uruchomić procedurę, zamiast uruchamiać procedurę bezpośrednio
  • napisać krótką procedurę, która aktualizuje tabelę statusu , używając PRAGMA AUTONOMOUS_TRANSACTION. Ta zasada umożliwia zatwierdzanie aktualizacji tabeli statusu bez konieczności wykonywania aktualizacji głównej procedury. Każdy ważny krok Twojej głównej procedury powinien mieć własny wpis w tabeli statusu.
  • napisać procedurę do kwerendy tabeli stanie się nazywać przez przeglądarkę
  • napisać procedurę, która jest wywoływana przez wywołania AJAX jeśli użycie klika „Anuluj” lub zamyka okno
  • napisać procedurę, która jest wywoływana według głównej procedury po zakończeniu każdego kroku: zapytuje tabelę statusu i zgłasza wyjątek z numerem w 20 000, jeśli flaga anulowania została ustawiona lub przeglądarka nie zapytała o status przez, powiedzmy, 60 sekund. W procedurze obsługi wyjątku dla procedury głównej dla tego błędu wykonaj wycofanie i zaktualizuj tabelę statusu.
Powiązane problemy