2011-09-05 6 views
7

Korzystam z .NET Framework 4.0, C# i SQL Server 2008 R2 w systemie Windows Server 2008 R2. Mój kontekst danych LINQ do SQL znajduje się w osobnej bibliotece, a dany kod działa w usłudze Windows.Czy istnieje błąd lub ograniczenie w LINQ do SQL, które spowodowałoby, że procedura przechowywana do limitu czasu?

Mam przetestowaną, krytyczną dla operacji procedurę przechowywaną, która pobiera 19 parametrów (wiem, że wiem), wykonuje proste logiki "if" i buduje kilka zmiennych oraz wstawia dane do 3 tabel. Nie używa kursorów ani tabel tymczasowych. Opisałem, co robi SP, ponieważ nie mam prawa publikować kodu SQL.

Widzę wiele postów w Internecie o SqlException z powodu timeout polecenia, a odpowiedzi rzadko wykraczają poza "zwiększyć timeout polecenia". Example

Otrzymałem powyższy wyjątek, więc próbowałem zwiększyć limit czasu polecenia podczas tworzenia kontekstu danych do 10 minut. Nadal mam wyjątek po tym, jak siedział tam i czekał na te 10 minut. Następnie dodałem kilka protokołów debugowania, aby przechwycić dane wyjściowe z LINQ do SQL i uruchomiłem SP w SQL Server Management Studio z tymi samymi wartościami parametrów. Pomyślnie zakończyła się w ułamku sekundy drugiej.

Oto LINQ to SQL wyjście Log (limity czasu z powrotem na domyślne) miesza się z jakiegoś innego wyjścia dziennika, mam ukrywane nazwy SP w tym poście:

16:01:37 15269 Irrelevant log line, deleted for StackOverflow 
EXEC @RETURN_VALUE = [dbo].[NAMEHIDDENONSTACKOVERFLOW] @Eastings = @p0, @Northings = @p1, @Speed = @p2, @UpdateDate = @p3, @UserId = @p4, @Postion = @p5, @Direction = @p6, @VehicleId = @p7, @Status = @p8, @Confidence = @p9, @Latitude = @p10, @Longitude = @p11, @PosLatitude = @p12, @PosLongitude = @p13, @WatchBoxId = @p14, @LastWatchBoxId = @p15, @WatchBoxIdAlert = @p16, @ImbolizationState = @p17, @TowAwayAlertState = @p18 
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [560120] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [5754714] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p3: Input DateTime (Size = -1; Prec = 0; Scale = 0) [02/08/2011 20:45:08] 
-- @p4: Input Int (Size = -1; Prec = 0; Scale = 0) [11] 
-- @p5: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [Swindon United Kingdom] 
-- @p6: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [5] 
-- @p7: Input Int (Size = -1; Prec = 0; Scale = 0) [15269] 
-- @p8: Input Int (Size = -1; Prec = 0; Scale = 0) [901] 
-- @p9: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p10: Input Float (Size = -1; Prec = 0; Scale = 0) [51.939899] 
-- @p11: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.125414] 
-- @p12: Input Float (Size = -1; Prec = 0; Scale = 0) [51.9333333] 
-- @p13: Input Float (Size = -1; Prec = 0; Scale = 0) [-2.1] 
-- @p14: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p15: Input Int (Size = -1; Prec = 0; Scale = 0) [-1] 
-- @p16: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p17: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p18: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @RETURN_VALUE: Output Int (Size = -1; Prec = 0; Scale = 0) [Null] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 

16:02:23 0 Error in DoPoll 1 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

jedyną wskazówką, że jestem pobieranie z przeszukiwania Stack Overflow polega na tym, że może wystąpić problem z czymś, co nazywa się "sniffingiem parametrów", ale wciąż czytam o tym, aby ustalić, o co chodzi.

To jest naprawdę krytyczna sprawa, a ja dostanę wiele kłopotów, jeśli nie uda się jej produkcji, więc mam ochotę wycofać LINQ i wrócić do waniliowej ADO. Moje pytanie brzmi: czy coś jest nie tak z moim podejściem (inaczej: czy jestem idiotą?) Czy jest jakiś problem lub błąd w LINQ do SQL, który może być przyczyną tego problemu? Czy jest coś, co mogę zrobić, aby rozwiązać ten problem, czy lepiej powrócić do waniliowej ADO?

+1

Kilka rzeczy do wypróbowania, jeśli chodzi o sniffowanie parametrów: http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/ i http: //stackoverflow.com/questions/6986607/a-5sec-sp-hitting-a-30sec-timeout-through-linq-to-sql/6986902#6986902 –

+0

http://stackoverflow.com/questions/211355/parameter- Sniffing-or-spoofing-in-sql-server jest całkiem niezły. –

+1

+1 za "Wiem, że wiem" :) – AakashM

Odpowiedz

0

Powróciłem do ADA vanila i otrzymałem ten sam wyjątek, więc odpowiedź brzmi "nie, to nie jest błąd LINQ do SQL". Ja również refaktoryzowałem SP za parametr wąchania artykułów i to nie pomogło. Ponieważ kod zaczął działać ponownie, mogę sobie tylko wyobrazić, że był to tymczasowy problem systemowy lub błąd bazy danych. Z korzyścią dla innych osób, które mają podobne problemy i znajdź to pytanie przez wyszukiwanie później, zaktualizuję dalej, jeśli znajdę coś więcej, ponieważ kolega wkrótce przetestuje kod w innym systemie.

EDYCJA: To był problem systemowy; w szczególności mój dysk VMWare wymagał defragmentacji.

(W przypadku porad dotyczących meta, powinienem opublikować własną odpowiedź, a nie aktualizować pytanie).

+0

Czy masz jakieś klauzule "IF" w SQL SP? Zauważyłem czasami zestaw raportów SQL 1, a czasem więcej. Spróbuję znaleźć kod, którego użyłem do ustalenia tego. – leppie

+0

Spróbuj uruchomić 'exec sys.sp_procedure_params_rowset 'yoursp'' kilka razy i sprawdź, czy dane wyjściowe pozostały niezmienione. – leppie

+0

Tak, istnieje kilka klauzul FI. –

0

LINQ-do-SQL wykorzystuje wanilię ADO.NET pod okładkami. Co najmniej w odniesieniu do ADO.NET i SQL Server, nie jesteś blisko maksymalizacji liczby parametrów, które mogą obsłużyć. LINQ-to-SQL jest bardzo przyjazny dla procedury przechowywanej, o ile przechowywany proc nie robi nic strasznego, jak tworzenie dynamicznego SQL wewnątrz procesu lub zwracanie wyników z tabel tymczasowych.

W jaki sposób tworzysz mapowanie Linq-SQL dla przechowywanego procesu? W zestawie SDK programu Visual Studio znajduje się narzędzie wiersza polecenia "SQLMETAL", które tworzy pliki .dbml i .cs, a jeśli jest określone przez przełącznik wiersza polecenia, również mapuje procedury przechowywane. Wykonuje on wystarczającą analizę procedur przechowywanych w celu sprawdzenia, czy LINQ to SQL obsługuje je, i przekaże komunikaty o błędach dotyczące przechowywanych procedur, które nie spełniają ich standardów. Spróbuj uruchomić SQLMETAL i sprawdź, jakie wiadomości otrzymasz.

+0

Dzięki Cylon. Jestem świadomy, że ADO waniliowe jest używane pod okładkami (w rzeczywistości wyjątek, który widzę jest wyjątkiem ADO), ale nie wiedziałem, że SqlMetal daje przydatne wyniki, więc spróbuję tego. Aby odpowiedzieć na twoje pytanie, generuję plik dbml, przeciągając i upuszczając procedurę przechowywaną z eksploratora serwerów do diagramu kontekstu danych w Visual Studio 2010. –

+0

Zawsze uważałem SqlMetal za lepsze narzędzie niż przeciąganie i upuść narzędzie wizualne (które uważam za demo-ware, a nie jako jakość produkcji).Linq-SQL ma pewne ograniczenia dla procedur przechowywanych i wiem, że SqlMetal je sprawdza. –

+0

Próbowałem tego, tylko jedno ostrzeżenie z niepowiązanego obiektu db. –

1

Założę się, że próbowałeś wydłużyć czas na twój kontekst danych Linq, jak wspomniałeś, że większość postów sugerowała to.

Jednak ...

Co wycieczki wiele osób w takich przypadkach jest to serwer WWW, szczególnie jeśli działa to na IIS7.

W przeszłości miałem przypadki, w których spędziłem niezliczoną ilość godzin na gonitwach, aby dowiedzieć się, na czym polega limit czasu, ale tylko w ciągu pięciu sekund, zmieniając wartości limitu czasu dla aplikacji serwera w IIS7 panel zarządzania.

Nie mówię, że jest to z pewnością problem, ale jeśli masz tylko serwer WWW ustawiony na 30 sekund (co jest domyślne) można usiąść i zmienić przerw czasowych w kontekście danych przez cały dzień, a ty Nigdzie nie dojdę.

Jeśli chcesz spróbować, zaloguj się do urządzenia, na którym działa serwer WWW, rozwiń serwer/witrynę w lewym panelu, aby przejść do aplikacji, z której uruchamiany jest zapisany proces.

W tym miejscu masz kilka miejsc do zobaczenia. Jeśli powrócisz do poziomu witryny EG: "Domyślna witryna internetowa" i kliknij na nią, a następnie kliknij ustawienia zaawansowane po prawej stronie i rozwiń limity połączeń, możesz ustawić liczbę sekund dla całej witryny.

Jeśli dzwonisz do SP z klasycznego pliku ASP, kliknij na swoją aplikację webową i kliknij dwukrotnie ikonę ASP w środkowym okienku, rozwiń opcję "Limits Properties" i zmień wartość limitu czasu skryptu, aby dopasować.

Na koniec, jeśli robisz to za pomocą jakiejś operacji CGI, kliknij na swoją aplikację internetową, a następnie kliknij dwukrotnie na CGI i zmień limit czasu tam.

Last but not least, jeśli żadna z powyższych pomocy, można spróbować dodać następujący fragment XML do aplikacji web.config pliku w odpowiednim miejscu, aby kontrolować czas wykonywania skryptu z .NET:

<system.web> 
     <httpRuntime executionTimeout="180"/> 
    <\system.web> 

Jeśli nie korzystasz z usług IIS7, musisz sprawdzić, w jakim panelu kontrolnym serwer używa podobnych ustawień.

+0

Dzięki za szczegółowe odpowiedzi shawty, ale niestety IIS nie jest częścią tego równania. To usługa Windows. –