Czy mogę uruchomić procedurę przechowywaną i natychmiast powrócić bez oczekiwania na jej zakończenie?

41

Mamy procedurę składowaną, którą użytkownicy mogą uruchomić ręcznie, aby uzyskać zaktualizowane numery raportu, który jest stale używany przez cały dzień.

Mam drugą procedurę przechowywaną, która powinna zostać uruchomiona po uruchomieniu pierwszej procedury przechowywanej, ponieważ jest ona oparta na liczbach uzyskanych z tej pierwszej procedury przechowywanej, jednak jej uruchomienie trwa dłużej i dotyczy osobnego procesu, więc nie chcę zmusza użytkownika do czekania na uruchomienie drugiej procedury składowanej.

Czy istnieje sposób, aby jedna procedura przechowywana rozpoczęła drugą procedurę przechowywaną i powróciła natychmiast, nie czekając na wyniki?

Używam SQL Server 2005.

Rachel
źródło
Jak wywoływane są procedury składowane? Aplikacja internetowa ASP.NET? SSRS?
Mr.Brownstone
@ Mr.Brownstone Zwykle jest wywoływany z aplikacji internetowej ASP.Net, chociaż może być wywoływany przez więcej niż jedną z nich. Musiałbym dwukrotnie sprawdzić. Czasami jest również uruchamiany ręcznie z SSRS.
Rachel
@MartinSmith Pracowałem kiedyś z brokerem usług SQL i miałem nadzieję, że będzie prostszy sposób. Wydaje się to tak złożoną konfiguracją czegoś tak prostego jak to.
Rachel
1
@MartinSmith to właściwie to, o czym myślałem - również, jeśli chodzi o SSRS nie, nie możesz, ale to, co możesz zrobić, to włączyć Przeglądarkę raportów do aplikacji i przenieść do niej pliki rdl - w ten sposób można wykonywać połączenia asynchroniczne również dla raportów.
Mr.Brownstone

Odpowiedzi:

27

Wygląda na to, że istnieje wiele sposobów na osiągnięcie tego, ale najprostszym sposobem była sugestia Martina, aby skonfigurować procedurę w zadaniu SQL i uruchomić ją za pomocą asynchronicznej komendy sp_start_job z mojej procedury składowanej.

EXEC msdb.dbo.sp_start_job @job_name='Run2ndStoredProcedure'

Działa to tylko dla mnie, ponieważ nie muszę określać żadnych parametrów dla mojej procedury składowanej.

Inne sugestie, które mogą działać w zależności od twojej sytuacji, to:

  • Korzystanie z brokera usług SQL, jak sugerują Martin i Sebastian . Jest to prawdopodobnie najlepsza sugestia, jeśli nie przeszkadza Ci złożoność konfiguracji i nauczenie się, jak to działa.
  • Asynchroniczne uruchamianie procesu w kodzie odpowiedzialnym za wykonanie procedury składowanej, jak sugerował Mr.Brownstone .

    Nie jest to zły pomysł, jednak w moim przypadku procedura przechowywana jest wywoływana z wielu miejsc, więc znalezienie wszystkich tych miejsc i upewnienie się, że wywołują również drugą procedurę, nie wydawało się praktyczne. Również druga procedura przechowywana jest dość krytyczna, a jej pominięcie może spowodować poważne problemy dla naszej firmy.

  • Ustaw pierwszą procedurę, aby ustawić flagę, i skonfiguruj cykliczne zadanie, aby sprawdzić tę flagę i uruchomić, jeśli jest ustawiony, jak sugerował Jimbo . Nie jestem wielkim fanem zleceń, które działają stale i sprawdzają zmiany co kilka minut, ale z pewnością jest to opcja warta rozważenia w zależności od twojej sytuacji.
Rachel
źródło
3
Spójrz na wykonanie procedury asynchronicznej, aby uzyskać gotowy przykład użycia za pomocą Service Broker. Zaletą sp_job jest to, że działa on w wersji Express Edition i jest całkowicie oparty na DB (brak zależności od tabel zadań MSDB). To ostatnie jest bardzo ważne w przypadku przełączania awaryjnego DBM i odzyskiwania HA / DR.
Remus Rusanu
Strzelaj, widzę, że Martin łączy ten sam artykuł. Zostawię komentarz do argumentów trybu failover / DR.
Remus Rusanu
@RemusRusanu: cóż, to jedno z najlepszych źródeł informacji na temat brokera usług, ale przypuszczam, że już to wiedziałeś ;-).
Marian
Podobał mi się link z @Rusanu, ale chciałem czegoś bez odpowiedzi (co moim zdaniem pasuje do tego problemu). Swoją
Abacus
Ponadto, jeśli spróbujesz uruchomić zadanie agenta SQL, zakończy się ono niepowodzeniem, ponieważ na platformie EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.Azure nie istnieje również ani broker usług, ani agent Sql. Nie wiem, dlaczego Microsoft, po półtorej dekadzie ludzi, odmawia dodania EXECUTE ASYNC RematerializeExpensiveCacheTable.
Ian Boyd
8

Możesz użyć brokera usług wraz z aktywacją w kolejce. Dzięki temu możesz opublikować parametry wywołania procedury w kolejce. Zajmuje to tyle samo czasu co wkładka. Po zatwierdzeniu transakcji i potencjalnie kilku sekundach aktywacja automatycznie wywoła procedurę odbiorcy asynchronicznie. To po prostu wuold musi wziąć parametry kolejki i wykonać pożądaną pracę.

Sebastian Meine
źródło
7

To stare pytanie zasługuje na bardziej wyczerpującą odpowiedź. Niektóre z nich są wymienione w innych odpowiedziach / komentarzach tutaj, inne mogą, ale nie muszą, działać w konkretnej sytuacji OP, ale mogą działać dla innych, którzy szukają wywoływania przechowywanych procedur asynchronicznie z SQL.

Wystarczy być całkowicie jednoznaczne: TSQL czy nie (przez siebie) mają zdolność do uruchomienia innych operacji TSQL asynchronicznie .

To nie znaczy, że wciąż nie masz wielu opcji:

  • Zadania agenta SQL : Utwórz wiele zadań SQL i albo zaplanuj ich uruchomienie w żądanym czasie, albo uruchom je asynchronicznie z poziomu „kontroli nadrzędnej” przechowywanej przy użyciu sp_start_job. Jeśli chcesz programowo monitorować ich postęp, po prostu upewnij się, że zadania aktualizują niestandardową tabelę JOB_PROGRESS (lub możesz sprawdzić, czy zakończyły się jeszcze przy użyciu funkcji nieudokumentowanej, xp_sqlagent_enum_jobsjak opisano w tym doskonałym artykule Gregory A. Larsen). Musisz utworzyć tyle osobnych zadań, ile chcesz, aby działały równoległe procesy, nawet jeśli działają na tym samym przechowywanym proc z różnymi parametrami.
  • Pakiet SSIS : w przypadku bardziej skomplikowanych scenariuszy asynchronicznych utwórz pakiet SSIS z prostym przepływem zadań rozgałęziających. SSIS uruchomi te zadania w poszczególnych spidach, które SQL będzie wykonywać równolegle. Wywołaj pakiet SSIS z zadania agenta SQL.
  • Aplikacja niestandardowa : Napisz prostą aplikację niestandardową w wybranym języku (C #, Powershell itp.), Korzystając z metod asynchronicznych udostępnianych przez ten język. Wywołaj SQL przechowywany proc w każdym wątku aplikacji.
  • Automatyzacja OLE : w SQL użyj sp_oacreatei sp_oamethoduruchom nowy proces, wywołując nawzajem przechowywane procedury, jak opisano w tym artykule , również przez Gregory'ego A. Larsena.
  • Service Broker : Spójrz na używanie Service Broker , dobry przykład asynchronicznego wykonania w tym artykule .
  • Równoległe wykonywanie CLR : użyj poleceń CLR Parallel_AddSqli Parallel_Executezgodnie z opisem w tym artykule Alana Kaplana (tylko SQL2005 +).
  • Zaplanowane zadania Windows : Wymienione dla kompletności, ale nie jestem fanem tej opcji.

Gdybym to był ja, prawdopodobnie użyłbym wielu zadań agenta SQL w prostszych scenariuszach, a pakiet SSIS w bardziej złożonych scenariuszach.

W twoim przypadku wywoływanie zadań SQL Agent brzmi jak prosty i łatwy do zarządzania wybór.

Ostatni komentarz : SQL już teraz próbuje zrównoważyć poszczególne operacje, kiedy tylko jest to możliwe *. Oznacza to, że uruchomienie 2 zadań jednocześnie zamiast po sobie nie gwarantuje, że zakończy się wcześniej. Przetestuj dokładnie, aby zobaczyć, czy rzeczywiście coś poprawia, czy nie.

Mieliśmy programistę, który utworzył pakiet DTS do uruchamiania 8 zadań jednocześnie. Niestety był to tylko serwer 4-procesorowy :)

* Zakładając domyślne ustawienia. Można to zmodyfikować, zmieniając maksymalny stopień równoległości lub maskę koligacji na serwerze, lub stosując wskazówkę dotyczącą zapytania MAXDOP.

BradC
źródło
6

Tak, jedna metoda:

  1. Po zakończeniu 1. procedury składowanej wstawia rekord ze wszystkimi informacjami potrzebnymi do uruchomienia drugiej procedury składowanej
  2. Druga procedura przechowywana jest uruchamiana jako zadanie, co minutę lub o której godzinie zdecydujesz
  3. Sprawdza wstawione rekordy, wykonuje ich przetwarzanie i oznacza rekord jako kompletny
Jimbo
źródło
Ogranicza to wykonywanie procedury składowanej do liczby uruchomionych zadań, co jest w porządku, jeśli tylko chcesz, aby to było wywoływane przez jednego klienta na raz - podczas gdy wielu klientów może wywoływać tę samą procedurę w tym samym czasie . Ponadto, skąd klient wiedziałby, że zadanie zostało zakończone bez wielokrotnego przeszukiwania bazy danych w celu ustalenia, czy ustawiono flagę?
Mr.Brownstone
1
@ Mr.Brownstone - Potencjalnie zadanie może przetworzyć więcej niż jedno zaległe zadanie ustawione w kolejce przez różne wywołania procedur składowanych podczas jego działania. Procedura składowana może również wywoływać, sp_start_jobaby ją uruchomić lub dynamicznie tworzyć zadania w razie potrzeby, aby uniknąć odpytywania co minutę, ale złożoność w tym przypadku prawdopodobnie oznacza, że ​​nie będzie prostsza niż broker usług.
Martin Smith
@MartinSmith W rzeczywistości mam już konfigurację zadania dla tej drugiej procedury składowanej, ponieważ była ona uruchamiana co noc, dopóki nie znaleźliśmy problemów z niepoprawną synchronizacją z numerami pierwszej procedury. Czy jeśli rozpocznę zadanie od 1. procedury składowanej, czy będzie działać asynchronicznie i natychmiast powróci z SP?
Rachel
@Rachel - Tak. sp_start_jobwraca natychmiast. Nie pamiętam jednak, jakich uprawnień potrzebuje.
Martin Smith
1
Rozpoczęcie pracy z innej procedury / bazy danych jest dość złożonym problemem, jeśli nie chcesz otwierać dużych luk bezpieczeństwa. Erland Sommarskog ma artykuł na temat różnych technik, które należy połączyć: sommarskog.se/grantperm.html Jednak nie ma tam kompletnego rozwiązania.
Sebastian Meine
1

Inną możliwością byłoby uzyskanie pierwszej procedury składowanej w celu zapisania do tabeli kontroli po jej zakończeniu i umieszczenie wyzwalacza w tabeli kontroli, która uruchamia drugą procedurę przechowywaną, gdy tabela kontroli zostanie zapisana. Nie ma potrzeby ciągłego odpytywania ani dodatkowej pracy agenta SQL Server.

paco
źródło
3
Pierwsza procedura składowana nie powróci, dopóki wstawianie do tabeli kontroli nie zakończy się, i nie stanie się tak, dopóki wyzwalacz nie zakończy działania (w tym wywołanie drugiej procedury składowanej)
Martin Smith
1
Już zastanawiałem się nad użyciem wyzwalacza, ale wyzwalacze są uruchamiane synchronicznie z instrukcją INSERTlub UPDATE, a nie asynchronicznie, więc Martin ma rację, że pierwsza procedura nadal kończy się na czekaniu, aż druga procedura zakończy się powrotem.
Rachel