2014-08-27 19 views
5

Vòng lặp có thể tự khóa không?Vòng lặp có thể tự khóa không?

Đêm qua, nhóm thử nghiệm đã mở một dấu lạ. Ứng dụng có lưới điện nơi người dùng có thể kiểm tra các sự cố bị hoãn người thử nghiệm đã chọn hai sự cố (id: 1 và 5), bị hoãn cả hai nhưng không có trạng thái được cập nhật

Tôi biết [Sự cố] bảng phải được cập nhật và một kỷ lục mới chèn vào bảng [IncidentDetail] tôi truy vấn cả và thiên này:

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 

các thử phàn nàn là hợp lệ vì cả hai [Incident] [IncidentStatus] giá trị phải bằng không tại này. điểm. Sau khi đào sâu vào nó, tôi đã chụp chính xác truy vấn mà ứng dụng được gửi tới máy chủ (nhờ trình thu thập thông tin).

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 

Không kích hoạt, không cập nhật khác không có giao dịch đang chờ xử lý. Theo tôi biết, ngay cả khi vòng lặp đầu tiên lặp lại bị chặn thứ hai đến điểm cập nhật thất bại, một ngoại lệ phải được nâng lên và tất cả các giao dịch được cuộn lại.

Dường như bản cập nhật không chính xác có thể bị lỗi trong khi quá trình chèn hoạt động. Tất cả các cột có các loại standart (Int, Varchar (100), DateTime, vv) cũng được thử nghiệm cho các vấn đề ẩn.

Sự cố này chỉ xảy ra một lần và không thể sao chép được, ngay cả khi sử dụng bản sao lưu nhưng tôi sợ nó có thể xảy ra lần nữa khi sản xuất nếu tôi không thể tìm thấy lý do tại sao nó xảy ra.

+0

Lỗi trong SQL Server đôi khi hủy bỏ lô, đôi khi không. Tương tự cho giao dịch và kết nối. (Vâng, điều này thật khó chịu.); Vì vậy, bản cập nhật của bạn có thể bị lỗi và quá trình chèn có thể đi qua. Có thể ứng dụng của bạn đang vứt bỏ lỗi. – usr

+0

Và không, giao dịch không thể tự khóa hoặc bế tắc. – usr

+0

Lỗi truy vấn nội bộ có thể và xảy ra. Tôi đã gặp chính họ trong mã sản xuất: http://blogs.msdn.com/b/bartd/archive/2008/09/24/today-s-annoyingly-unwieldy-term-intra-query-parallel-thread -deadlocks.aspx – Jace

Trả lời

3

Tôi không hiểu bạn thực sự muốn làm gì. Tôi đang cho bạn một cách dựa trên những gì tôi hiểu. Bạn có thể kiểm tra xem mục nhập đó có được cập nhật hay không, nếu được cập nhật thì bạn chèn vào 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

Sau một vài ngày chúng tôi phát hiện ra vấn đề là do một đồng nghiệp khác đã xóa một hàng và chúng tôi mù tin rằng đó không phải là vấn đề lúc đầu. Ngoài ra tôi tìm thấy rất nhiều tài liệu tham khảo nói rằng một vòng lặp không thể khóa chính nó (câu hỏi là ngớ ngẩn từ đầu và tôi bị bệnh đóng nó). Tôi bị bệnh không xóa nó để phục vụ như là một tài liệu tham khảo kể từ khi nhiều người truy cập nó. Ngoài ra, bạn cũng có thể trả lời câu trả lời của bạn vì nó có thể hữu ích cho ai đó – jean

Các vấn đề liên quan