2009-01-08 10 views
7

Chcę napisać usługę (prawdopodobnie w języku C#), która monitoruje tabelę bazy danych. Kiedy rekord zostanie wstawiony do tabeli, chcę, aby usługa chwyciła nowo wstawione dane i wykonała za to złożoną logikę biznesową (zbyt skomplikowaną dla TSQL).Czy wyzwalacze SQL CLR mogą to zrobić? Czy jest jakiś lepszy sposób?

Jedną z opcji jest okresowe sprawdzanie tabeli w celu sprawdzenia, czy dodano nowe rekordy. Problem polegający na tym, że chcę, aby usługa wiedziała o wstawkach, gdy tylko się pojawią, i nie chcę zabijać wydajności bazy danych.

Trochę badań, wydaje się, że może pisanie wyzwalacza CLR może wykonać zadanie. Mogę napisać wyzwalacz w języku C#, który uruchamia się po pojawieniu się wstawki, a następnie wysyła nowo wstawione dane do usługi Windows lub WCF.

Co sądzisz, czy to dobre (lub możliwe) użycie wyzwalaczy SQL CLR?

Jakieś inne pomysły, jak to osiągnąć?

Odpowiedz

6

Prawdopodobnie należy de-para postprocessing z włożeniem:

W spuście Wstaw PK dodać rekord do tabeli w kolejce.

W oddzielnej usłudze odczytaj z tabeli kolejki i wykonaj złożoną operację. Po zakończeniu zaznacz rekord jako przetworzony (razem z informacją o błędzie/stanie) lub usuń rekord z kolejki.

+0

Dokładnie to, co miałem zasugerować. Będzie on bezpieczny pod względem transakcji i będzie przechowywać przetworzone i nieprzetworzone rekordy w tabeli, która nie wpłynie na główne tabele aplikacji. +1 dla tego rozwiązania! – evilhomer

+2

Użyj programu SQL Server Service Broker –

+0

Dobry pomysł, z tym wyjątkiem, że tracisz cały ślad rzeczy, które uległy zmianie (tj. Zawartość tabeli DELETED, dostępna tylko podczas wykonywania wyzwalacza). Zależy od tego, czego potrzebujesz, przypuszczam. –

3

To, co opisujesz, jest czasami nazywane Kolejką zadań lub Kolejką wiadomości. Istnieje kilka wątków dotyczących używania tabeli DBMS (a także innych technik) do robienia tego, co można znaleźć przez wyszukiwanie.

Uznalbym, że robienie czegokolwiek w tym stylu za pomocą wyzwalacza jest niewłaściwym wykorzystaniem funkcji bazy danych, która i tak łatwo wpada w kłopoty. Wyzwalacze najlepiej nadają się do strukturalnej funkcjonalności DBMS o niskim obciążeniu (na przykład dokładnego sprawdzania integralności referencyjnej) i muszą być lekkie i synchroniczne. Można to zrobić, ale prawdopodobnie nie byłby to dobry pomysł.

1

Mam usługę, która odpytuje bazę danych co minutę, nie powoduje tak dużych problemów z wydajnością i jest czystym rozwiązaniem. Plus jeśli twoja usługa lub inny punkt końcowy nie jest tam, twój wyzwalacz się nie powiedzie lub zaginie i będziesz musiał sondować w każdym razie później.

1

Nie polecam używania wyzwalacza CLR ani żadnego innego wyzwalacza do tego. Otwierasz się na poważną konserwację i potencjalne problemy z blokowaniem. (Bardzo prosty mechanizm uruchamiający, który przenosi elementy do tabeli audytu/kolejki może być akceptowany, jeśli nie interesuje Cię tożsamość @@ po wstawieniu i nigdy nie zablokujesz tabeli kontroli/kolejki)./orm powinieneś wywołać wstawianie rzeczy do tabeli kolejki i regularnie przetwarzać tę kolejkę. Można to zrobić, dokonując transakcji w ORM lub uruchamiając zapisany proces, który rozpoczyna transakcję, a następnie zatwierdza zmianę i audyt/kolejkę atomowo. (Należy uważać z blokadą tutaj)

Jeśli potrzebujesz natychmiastowego działania, spójrz na tarło zadanie wyczyścić kolejkę po wykonaniu insert/update/delete na stole i

zapewniają również jesteś podwójne sprawdzanie ustawiaj kolejkę raz na minutę w przypadku, gdy proces w tle nie został poprawnie uruchomiony. Jeśli jest to aplikacja internetowa i chcesz uniknąć wątków odradzania, możesz komunikować się z procesem działającym w tle, aby wyczyścić kolejkę.

-1

Dlaczego nie zaimplementować wstawki w procedurze przechowywanej i wykonać logikę biznesową w procedurze po wstawieniu? Co jest tak skomplikowane, że nie można go napisać w T-SQL?

2

Proponuję mieć wyzwalacz w tabeli, który wywołuje SQL Server Service Broker, który następnie (asynchronicznie) wykonuje procedurę przechowywaną CLR, która wykonuje całą pracę w innym wątku.

+0

Uzgodnione. Kod .net nie musi być procrem przechowywanym przez clr - może pobierać zawartość kolejki z innego procesu. –