2014-10-07 11 views
5

Mam tabeli MSSQL, który zawiera zadania zaplanowane, że moje usługi Windows powinien proces oparty off znacznik czasu i zastanawiałem się, co alternatywy mam na odpytywanie tabeli jak tenAlternatywa dla tabeli MSSQL odpytywania

SELECT * 
FROM mydb 
WHERE SYSUTCDATE() >= timestamp 

I” Prawdopodobnie musisz odpytywać tabelę przynajmniej co 5 sekund. Zasadniczo chcę, aby moja usługa systemu Windows przetwarzała dane w czasie określonym przez znacznik czasu w tabeli.

Dla mnie nie wydaje się to najskuteczniejszym sposobem. Już sprawdziłem wyzwalacze CLR DML & i nie sądzę, że będą działać tak, jak będą strzelać, gdy dane ulegną zmianie, a nie gdy minie znacznik czasu. Myśli?


Aktualizacja 2:

zdałem sobie sprawę, że nazywając go „zaplanowane zadania” był ubogi wybór brzmienia, więc postaram się opisać to bardziej szczegółowo.

Celem tego projektu jest wysyłanie powiadomień telefonicznych do osób w zależności od naszej logiki biznesowej. Jeden scenariusz polega na tym, że wielu ludzi powinno być dzwonionych w określonych godzinach w oparciu o zdarzenie wewnętrzne. Ta sama osoba może zostać wywołana wiele razy w zależności od tego, jak odebrano połączenie telefoniczne. W ten sposób, aby uprościć rzeczy i usunąć złożoność i obciążenie związane z zarządzaniem stanem każdego połączenia telefonicznego, pomyślałem, że dobrym pomysłem byłoby przewidywanie każdego połączenia telefonicznego poprzez wpisanie go jako wpis w tabeli. Gdy powiadomienia mają zostać zatrzymane, oczekujące połączenia telefoniczne są usuwane z tabeli. Ułatwi to projektowanie systemu Windows. Wszystko, co można zrobić, to wysłać powiadomienie na podstawie jego znacznika czasu w tabeli.


Aktualizacja 1:

Message Queue

nie zorientowali się, jak nadawca wiadomości będzie można umieścić na kolejce w odpowiednim czasie.

SqlDependency

Mam problem przy użyciu kodu przykład od Detecting Changes with SqlDependency. Z jakiegoś powodu zdarzenie OnChange jest uruchamiane tylko na początku, nic się nie dzieje później.

Aktualizacja: Nie sądzę, że SqlDependency będzie działać, ponieważ dane w tabeli nie zmienią się, aby wyzwalać wyzwalacz.

void Initialization() 
{ 
    // Create a dependency connection. 
    SqlDependency.Start(connectionString, queueName); 
} 

void SomeMethod() 
{ 
    // Assume connection is an open SqlConnection. 

    // Create a new SqlCommand object. 
    using (SqlCommand command=new SqlCommand(
     "SELECT timestamp,othercolumn FROM mydb WHERE SYSUTCDATE() >= timestamp", 
     connection)) 
    { 

    // Create a dependency and associate it with the SqlCommand. 
    SqlDependency dependency=new SqlDependency(command); 
    // Maintain the refence in a class member. 

    // Subscribe to the SqlDependency event. 
    dependency.OnChange += new OnChangeEventHandler(OnDependencyChange); 

    // Execute the command. 
    using (SqlDataReader reader = command.ExecuteReader()) 
    { 
     // Process the DataReader. 
    } 
} 
+7

Czy rozważałeś zamiast tego używać kolejki wiadomości? – recursive

+3

Spróbuj SqlDependency: http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx –

+2

Czy rozważałeś zamianę tych zadań na zadania i uruchamianie ich za pośrednictwem SQL Server Agent? –

Odpowiedz

3

OK, przede wszystkim, nie rób tego w ogóle. Przesunięcie całej przydatnej pracy do zadań okresowych, które są konfigurowane w bazie danych, jest delikatnym projektem, który łatwo ulega zepsuciu, gdy ktoś źle skonfiguruje elementy (łatwe do zrobienia, ponieważ potrzebujesz dość zaawansowanych wyzwalaczy, aby sprawdzić spójność harmonogramu), a także ma tendencję do stwórz system, który jest niezrozumiały, gdy zadania rzeczywiście mają ukryte zależności (jeśli A nie trwa jakiś czas przed B, rzeczy się psują, tego typu rzeczy). Źródło: osobiste doświadczenia z trzema takimi systemami w trzech różnych firmach i trzech różnych platformach/technologiach i jakoś wszystkie one cierpiały z powodu tych samych problemów, więc najwyraźniej to jest rzecz. Rozważ napisanie rzeczy, które chcesz zaplanować jako zwykły stary kod, z plikiem konfiguracyjnym. Oczywiście, nie będzie to tak ogólne, ale ludzie, którzy muszą go utrzymywać, będą ci wdzięczni, zwłaszcza że ich potrzeby stają się bardziej złożone.

SqlDependency jest raczej zmienny i nie jest łatwy w użyciu, nawet jeśli masz zapytanie, które jest obsługiwane. W twoim przypadku, jak zauważyłeś, to nie działa, ponieważ silnik bazy danych nie wysyła powiadomienia, chyba że dane rzeczywiście się zmieniają - nie ma znaczenia, że ​​wyniki zapytania zmienią się z upływem czasu. Jak zauważył Nick, odpytywanie bazy danych co 5 sekund jest zazwyczaj w porządku. Daje to znikomy ładunek, pod warunkiem, że utworzyłeś indeks na mydb.timestamp (i że utworzenie go jest dość istotne, ponieważ przeprowadzanie skanowania tabeli co 5 sekund to , a nie OK).

Jedynym zastrzeżeniem jest opóźnienie: jeśli jakiekolwiek aktualizacje harmonogramu muszą nastąpić wcześniej niż raz na 5 sekund, odpytywanie nie jest wystarczająco dobre. W takim przypadku możesz użyć Service Broker i wysłać powiadomienie do kolejki, gdy tylko coś się zmieni (być może z powodu wyzwalacza). W rzeczywistości, SqlDependency używa tego samego podejścia pod okładkami, więc możesz utworzyć zależność od SELECT * FROM table, aby otrzymać powiadomienie, gdy tylko coś zmieni się w tabeli, a następnie wykonać rzeczywiste zapytanie, aby uzyskać to, czego potrzebujesz (ewentualnie dowiedzieć się, że nie ma nic). Uważaj jednak: uzyskanie poprawnego kodu bez pomyłek przez wiele szybkich aktualizacji lub przerwanie połączenia nie jest banalne i prawdopodobnie nie warto, w przeciwieństwie do zwykłego ponownego ładowania.

+0

Dzięki za szczegółową odpowiedź. Moje uzasadnienie dla przełożenia wszystkich zadań w bazie danych było spowodowane tym, że myślałem, że to uprościłoby sprawy, ponieważ byłoby zbyt duże obciążenie dla programowego zarządzania. Przekażę więcej informacji w moim OP. – user3811205