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.
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
I nie, transakcja nie może zablokować ani zakleić się. – usr
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