2015-05-15 26 views
5

Mam ten dziwny problem w mojej aplikacji. Zdarza się to bardzo rzadko lub raz, może dwa razy w tygodniu. Więc w zasadzie tutaj jest sytuacja:Sql Server Transaction Commit out time out

Mam tę metodę w mojej aplikacji, która kwerendy DB kilka razy, najpierw są 4 wybory, jeden z nich używa słowa kluczowego UPDLOCK następnie następuje wstawić do drugiej tabeli (nie do której do UPDLOCK) i aktualizację tabeli, która poprzednio była UPDLOCK -ed.

Wszystkie te zapytania są wykonywane w jednej transakcji (która znajduje się po stronie .NET), a na końcu dostaje COMMIT -ed.

Teraz problemem jest to, że transaction.Commit() rzuca wyjątek z komunikatem

Timeout minął. Okres oczekiwania upłynął przed zakończeniem operacji lub serwer nie odpowiada

(jak sądzę, SqlConnection przekroczeń czasu).

Więc mam całą tę procedurę zawinięte w try-catch bloku, a jeśli wystąpi wyjątek staram się cofnąć transakcję tak, kiedy to nastąpi wykonanie kodu idzie catch bloku i transaction.RollBack() nazywa a także rzuca wyjątek z komunikatem

Ta usługa SqlTransaction została zakończona. nie jest już użyteczne

(jak myślę, kiedy COMMIT razy na transakcji faktycznie dostaje COMMIT -ed), więc po tym niektóre części aplikacji bałagan. Rzecz, która prawdopodobnie nie istnieje (z powodu ROLLBACK) faktycznie istnieje i powoduje pewne nieoczekiwane problemy, które następnie są ręcznie naprawiane (w tej chwili).

Nie mogłem znaleźć niczego, co mogłoby wskazywać na problem, zamiast zwiększać limit czasu na SqlConnection. Jeśli ktoś poradził sobie z tym problemem, zanim zechcesz podzielić się doświadczeniem, z góry dziękuję. (DB wykorzystanie procesora serwera nie przekroczy 45-50%, jest w większości przypadków to idles na 3-15%)

Oto pierwsza SQL SELECT --first Wybierz

SELECT TOP 1 
      t.Id , 
      t.OId , 
      t.Amount , 
    t.DUserId, 
      t.StartDate , 
      t.ExtDesc, 
    t.StatusId 
    FROM dbo.[Transaction] t 
      JOIN dbo.Wallet cw ON t.CId = cw.Id 
      JOIN dbo.Wallet dw ON t.DId = dw.Id 
    WHERE ExtKey = @ExtKey 
      AND (cw.vId = @vId 
        OR dw.VId = @vId 
       ) 

--Second Selct which executes twice with differenc params 


    SELECT u.Id , 
      UserName , 
      PinCode , 
      CurrencyId , 
      StatusId , 
      PersonalNumber , 
      gu.DefaultVendorServiceId , 
      CountryId, 
    u.FirstName, 
    u.LastName 
    FROM dbo.[User] u 
      LEFT JOIN dbo.GamblerUser gu ON gu.UserId = u.Id 
    WHERE u.Id = @UserId 


--Last select with (updlock) 


SELECT w.Id, AccountNo, FundTypeId, VendorServiceId, Balance, UserId, vs.IsLocalAccount 

FROM Wallet w (UPDLOCK) 
JOIN VendorService vs on w.VId = vs.Id 
WHERE 
    w.UserId = @UserId 
AND w.FundTypeId = @FundTypeId 
AND w.VendorServiceId = @VendorServiceId 


-- Insert 


    INSERT INTO [dbo].[Transaction] 
      (StartDate , 
       OTypeId , 
       StatusId , 
       Amount , 
       ExtDesc, 
       DUserId 
      ) 
    VALUES     (@StartDate , 
       @OTypeId , 
       @StatusId , 
       @Amount , 
       @ExtDesc, 
       @DUserId 
      ) 

    SET @Id = (SELECT @@IDENTITY 
      ) 


-- Update on updlocked table  


UPDATE dbo.Wallet SET 

    Balance = ISNULL(@Balance, Balance) 

WHERE Id = @Id 
+0

@MitchWheat Sql or C#? – Dimitri

+1

Wbrew powszechnemu przekonaniu, użytkownicy SO nie są medium i nie są w stanie zrealizować projektu astralnego przed komputerem, aby zobaczyć kod. Byłoby fajnie, gdybyś mógł opublikować fragment kodu. Życzę Wam dobrze – MickyD

+0

Dodałem kod – Dimitri

Odpowiedz

3

(Zakładam to nie jest Hekaton, który robi coś inaczej na commit.)

Zatwierdzenie zwykle zajmuje mało czasu. Jeden fizyczny zapis musi zostać zapisany w dzienniku, aw przypadku Mirroring/AG musi zostać wykonany objazd sieciowy. Jedna z tych rzeczy prawdopodobnie wstrzyma zobowiązanie tutaj.

Osobiście spotkałem się z tym problemem z przeciążonym odbieraniem lustrzanym.

Limit czasu zatwierdzenia nie może być zmieniony osobno (co uważam za defekt). Używany jest limit czasu połączenia.

Zbadaj podstawowe przyczyny, o których wspomniałem powyżej. Jako czas oczekiwania na zwiększenie limitu czasu obejścia.

W przypadku nieudanego zatwierdzenia nie można założyć, że transakcja została faktycznie zatwierdzona. (Jest to problem dwóch generałów, który jest ogólnie nierozwiązywalny.) Musisz wymyślić jakąś kontrolę, aby sprawdzić, czy baza danych zawiera oczekiwane zapisy, czy nie. Jest to bardziej powszechne na platformie Azure. Sprawdź wskazówki Azure.

+0

dzięki. wystąpił problem z siecią (baza danych jest dublowana) – Dimitri