2013-01-18 16 views
6

Jak mogę zapobiec problemom z blokowaniem między dwoma wyzwalaczami uruchamianymi przy tym samym zdarzeniu w tej samej tabeli?Dwa różne wyzwalacze aktualizacji dla tej samej tabeli

DB, nad którym pracuję, ma już jeden wyzwalacz aktualizacji, który jest zaszyfrowany i dlatego nie mogę go zmodyfikować. Zrobiłem kolejny wyzwalacz aktualizacji, aby wykonać kilka nowych zadań, działa poprawnie, gdy testuję go bezpośrednio w bazie danych, ale nie powiedzie się, gdy dokonuję aktualizacji produktu w aplikacji front-end. Wygląda na to, że gdy aktywny jest mój wyzwalacz, oba wyzwalacze nie działają. Otrzymuję komunikat "Dokument jest już otwarty, zwiększam jego wartość".

Czy to jest problem z blokowaniem?

Jest tam related question, gdzie ktoś mówi, że możemy mieć więcej niż jeden wyzwalacz (dla tego samego zdarzenia) na stole.

Oto mój kod wyzwalacze:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE TRIGGER [dbo].[tr_st_rep_update] 
ON [dbo].[st] 
AFTER UPDATE 
AS 
    BEGIN 
     SET NOCOUNT ON; 

     IF (update(ref) 
      OR update(design) 
      OR update(u_update) 
      OR update(u_ativo) 
      OR update(stock) 
      OR update(epv1) 
      OR update(epv2) 
      OR update(epv3) 
      OR update(peso) 
      OR update(u_catnv1) 
      OR update(u_catnv2) 
      OR update(u_catnv3) 
      OR update(u_dpromoi) 
      OR update(u_dpromof) 
      OR update(u_destaque)) 
     BEGIN 
      IF (SELECT count(*) 
       FROM Inserted 
         INNER JOIN Deleted 
         ON Inserted.ststamp = Deleted.ststamp 
       WHERE inserted.u_ativo = 1 
         OR (Deleted.u_ativo = 1 
          AND Inserted.u_ativo = 0)) > 0 
       BEGIN 
        INSERT INTO RepData 
           (id, 
           REF, 
           familia, 
           stock, 
           epv1, 
           epv2, 
           epv3, 
           peso, 
           u_accao, 
           imagem, 
           process) 
        SELECT Inserted.ststamp AS id, 
         Inserted.REF  AS REF, 
         Inserted.familia AS familia, 
         Inserted.stock AS stock, 
         Inserted.epv1 AS epv1, 
         Inserted.epv2 AS epv2, 
         Inserted.epv3 AS epv3, 
         Inserted.peso AS peso, 
         CASE 
          WHEN Deleted.u_ativo = 1 
           AND Inserted.u_ativo = 0 THEN 'd' 
          ELSE 'u' 
         END    AS u_accao, 
         Inserted.imagem AS imagem, 
         0    AS process 
        FROM Inserted 
         INNER JOIN Deleted 
          ON Deleted.ststamp = Inserted.ststamp 
        WHERE inserted.u_ativo = 1 
          OR (Deleted.u_ativo = 1 
           AND Inserted.u_ativo = 0) 
       END 
     END 
    END 

Każda pomoc będzie mile widziane.

Aktualizacja: baza danych MSSQL 2008

+1

Czy możesz podać ** dokładny ** komunikat o błędzie (lub przynajmniej numer błędu, jeśli wiadomość nie jest w języku angielskim). "Dokument jest już otwarty, zwiększam jego wartość" nie brzmi jak komunikat o błędzie SQL Server. –

+0

Nie otrzymuję żadnej innej wiadomości niż ta, nie jest ona nawet pokazywana jako błąd, ale wiadomość informacyjna.Operacją jest aktualizacja produktu, jeśli jest to istotne. – Fabio

+1

jeśli jego produkcja, sprawdź logi aplikacji to musi gdzieś napisać, jeśli nie uruchom profilera na db i zobacz, co się dzieje – WKordos

Odpowiedz

0

Problem rozwiązany.

Naprawdę nie znam źródła problemu, chociaż myślę, że jest to coś związanego z blokowaniem tabeli, w tym przypadku z tabelą Wstawioną.

Właśnie zmieniłem wewnętrzne polecenie select, tak że pobieram wartości bezpośrednio z tabeli st zamiast z Włożonego.

Dziękuję wszystkim.

+1

Ah, OK. Oznacza to, że innym wyzwalaczem było zmodyfikowanie wierszy [st] table, które byłyby odzwierciedlone w [st], ale nie w [insert]. Sądzę, że spowodowało to jakieś kluczowe naruszenie w innym miejscu (prawdopodobnie w [RepData]). – RBarryYoung

8

Używanie wyzwalaczy do tworzenia i personalizacji po wdrożeniu w witrynie jest nęcącym, ale złym pomysłem i bez wątpienia będzie generować takie problemy.

Jednak biorąc pod uwagę to, to najpierw: tabele mogą mieć wiele wyzwalaczy, to nie problem.

Po drugie, komunikat o błędzie " Dokument jest już otwarty, zwiększam jego wartość" jest albo z aplikacji klienckiej, albo z innego (zaszyfrowanego) wyzwalacza, NIE jest to komunikat o błędzie SQL Server. Biorąc pod uwagę, że prawdopodobnie możesz spróbować albo ustawić zaszyfrowany wyzwalacz, aby wykonać jako pierwszy, albo ustawić swój wyzwalacz, aby wykonać ostatni. Prawdopodobnie nie rozwiąże to problemu, ale może przenieść błąd z zaszyfrowanego wyzwalacza do wyzwalacza, w którym masz większą szansę na zgłoszenie i/lub zaadresowanie go w łatwy sposób.

Choć z drugiej strony, jedynym problemem, który może być prawdopodobny z powodu wyzwalacza, jest to, czy drugi wyzwalacz również zapisuje do tabeli RepData, a podwójne pisanie powoduje duplikowanie naruszeń kluczy.


wyzwalania kolejność może być kontrolowana poprzez procedurę systemu sp_settriggerorder, co udokumentowano here.

+0

Dobra odpowiedź, dziękuję! Jak więc zarządzać kolejnością wykonywania wyzwalaczy? – Fabio

Powiązane problemy