2014-08-27 13 views
5

Czy sama pętla może się blokować?Czy sama pętla może się blokować?

Ostatniej nocy zespół testowy otworzył dziwny zaznaczone. Aplikacja posiada siatkę, w której użytkownik może sprawdzić incydentów zostać przełożone tester wybiera dwa wypadki (identyfikatory: 1 i 5), ale przesunięte zarówno jeden nie dostał status aktualizowane

znam [Incident] stół musi być aktualizowana i jeden nowy rekord wstawiony w [IncidentDetail] Tablica zapytaliśmy obu i lubię to:

Id IncidentKindCode TransportEntryId CreateDate    IncidentStatus CloseDate 
-- ---------------- ---------------- ---------------------- -------------- --------- 
1 11301   52    2014-08-26 19:23:21.47 1    NULL 
5 11301   56    2014-08-26 20:06:17.94 0    NULL 

Id IncidentId InsertDate    DetailKind Reason IncidentUser PostponeDate 
-- ----------- ---------------------- ---------- --------- ------------ ----------------------- 
9 1   2014-08-26 20:28:37.37 1   TEST TEST 8   2014-08-27 00:00:00.000 
10 5   2014-08-26 20:28:37.37 1   TEST TEST 8   2014-08-27 00:00:00.000 

tester skarżą jest ważna, ponieważ zarówno [Incident] [IncidentStatus] wartości musi wynosić zero na to. punkt. Po wykopaniu w nim przechwyciłem dokładne zapytanie o aplikację wysłaną na serwer (dzięki profilerowi).

declare @p1 int 
set @p1=2 
exec sp_prepexec @p1 output,N'@IDINCIDENT varchar(max) ,@REASON varchar(max) ,@USERCODE varchar(max) ,@POSTPONEDATE varchar(max) ',N' 
DECLARE @ARRAY VARCHAR(8000), @DELIMITADOR VARCHAR(100), @SELECTEDID VARCHAR(8000); 

SELECT @ARRAY = @IDINCIDENT 
SELECT @DELIMITADOR = '';'' 

IF LEN(@ARRAY) > 0 SET @ARRAY = @ARRAY + @DELIMITADOR 

WHILE LEN(@ARRAY) > 0 
BEGIN 

    SELECT @SELECTEDID = LTRIM(SUBSTRING(@ARRAY, 1, 
    CHARINDEX(@DELIMITADOR, @ARRAY) - 1)) 

    BEGIN 
     UPDATE [dbo].Incident SET INCIDENTSTATUS = 1 WHERE ID = @SELECTEDID 
     INSERT [dbo].IncidentDetail (INCIDENTID, DETAILKIND, REASON, INCIDENTUSER, POSTPONEDATE) 
         VALUES (@SELECTEDID, 1, @REASON, @USERCODE, @POSTPONEDATE); 
    END 

    SELECT @ARRAY = SUBSTRING(@ARRAY, 
    CHARINDEX(@DELIMITADOR, @ARRAY) + 1, LEN(@ARRAY)) 
END 
',@IDINCIDENT='1;5',@REASON='querty',@USERCODE='1',@POSTPONEDATE='2014-08-28 00:00:00' 
select @p1 

Brak wyzwalaczy, brak innych aktualizacji bez oczekujących transakcji. O ile wiem, nawet jeśli pierwsza iteracja pętli zablokowała drugi do punktu aktualizacja nie powiedzie się, wyjątek musi być podniesiony i cała transakcja zostać wycofana.

Wydaje ilogical aktualizacji może zabraknąć podczas wkładka działa. Wszystkie kolumny mają typy standardowe (Int, Varchar (100), DateTime, itd.) Również testowałem pod kątem problemów z niejawnymi rzutami.

Ten problem się tylko raz i nie może być powielana, nawet przy użyciu kopii zapasowej, ale obawiam się, że może zdarzyć się ponownie w produkcji, jeśli nie mogę znaleźć, dlaczego to się stało.

+0

Błędy w SQL Server czasami przerwać partii, czasem nie. To samo dotyczy transakcji i połączenia. (Tak, to jest paskudne.); Tak więc twoja aktualizacja może się nie udać i wkładka może przejść. Może twoja aplikacja wyrzuca błędy. – usr

+0

I nie, transakcja nie może zablokować ani zakleić się. – usr

+0

Zakleszczenia wewnątrz zapytania mogą się zdarzyć. Napotkałem je sobie w kodzie produkcji: http://blogs.msdn.com/b/bartd/archive/2008/09/24/today-s-annoyingly-unwieldy-term-intra-query-parallel-thread -deadlocks.aspx – Jace

Odpowiedz

3

Nie mam rozumieć to, co rzeczywiście chcesz zrobić. Daję ci sposób na podstawie tego, co rozumiem. Możesz sprawdzić, czy dany wpis zostanie zaktualizowany, czy nie, jeśli zaktualizujesz to wstawisz do IncidentDetail.

UPDATE [dbo].Incident SET INCIDENTSTATUS = 1 WHERE ID = @SELECTEDID 

If Exists( Select 1 
      From [dbo].Incident As I 
      Where I.ID = @SELECTEDID 
        And I.INCIDENTSTATUS = 1 
     ) 
Begin 
    INSERT [dbo].IncidentDetail (INCIDENTID, DETAILKIND, REASON, INCIDENTUSER, POSTPONEDATE) 
         VALUES (@SELECTEDID, 1, @REASON, @USERCODE, @POSTPONEDATE); 
End 
+0

Po kilku dniach stwierdziliśmy, że problem został spowodowany przez innego współpracownika, który usunął wiersz, a my ślepi byliśmy przekonani, że to nie był problem na początku. Również znalazłem wiele odniesień mówiących, że pętla nie może się zamknąć (pytanie było głupie od początku i źle to zamykam). Nie mogę go usunąć, aby służyć jako punkt odniesienia, ponieważ wiele osób go odwiedziło. Również źle przegłosuj swoją odpowiedź, ponieważ może być przydatna dla kogoś – jean

Powiązane problemy