Jaki jest efekt zbyt długiej otwartej transakcji w MSSQL?

11

Zastanawiam się tylko, co się stanie, jeśli rozpoczniesz transakcję w bazie danych i zapomnisz ją zatwierdzić lub wycofać. Czy serwer będzie wyłączony? Powiedzmy, że opuściłeś go na 3 dni.

Są też użytkownicy, którzy go używają, zakładając, że inni użytkownicy nie wiedzieli, że istnieje niezamknięta transakcja (załóżmy, że użytkownicy po prostu wstawiają dane do bazy danych). Jakie są konsekwencje tego działania?

JanLeeYu
źródło

Odpowiedzi:

14

Samo otwarcie transakcji nie będzie miało prawie żadnych konsekwencji. Prosty

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

będzie w najgorszym przypadku zawierać kilka bajtów wartości statusu. Nie ma sprawy.

Większość programów wykona rzeczywistą pracę w ramach transakcji, a to inna sprawa. Istotą transakcji jest to, że możesz być pewien, że kilka faktów w bazie danych jest jednocześnie prawdziwych, mimo że inni użytkownicy piszą do tej samej bazy danych jednocześnie.

Weź kanoniczny przykład transferu pieniędzy między kontami bankowymi. System musi upewnić się, że konto źródłowe istnieje, ma wystarczające fundusze, konto docelowe istnieje oraz że zarówno debet, jak i kredyt wystąpią lub nie wystąpią. Musi to zagwarantować, dopóki będą miały miejsce inne transakcje, być może nawet między tymi dwoma kontami. System zapewnia to, blokując dane tabele. Jakie blokady są podejmowane i ile pracy innych ludzi widzisz, jest kontrolowane przez poziom izolacji transakcji .

Jeśli wykonasz dużo pracy, istnieje duża szansa, że ​​w kolejce będą czekać inne transakcje na obiekty, na których trzymasz zamki. Spowoduje to zmniejszenie ogólnej przepustowości systemu. W końcu przekroczą limity czasu i przestaną działać, co stanowi problem dla ogólnego zachowania systemu. Jeśli użyjesz optymistycznego poziomu izolacji, transakcja może się nie powieść podczas próby zatwierdzenia z powodu pracy innej osoby.

Trzymanie zamków zabiera zasoby systemowe. Jest to pamięć, której system nie może wykorzystać do przetwarzania innych żądań, co zmniejsza przepustowość.

Jeśli wykonano dużo pracy, system może zdecydować się na eskalację blokady . Zamiast blokować poszczególne rzędy cały stół zostanie zablokowany. Wpłynie to na większą liczbę jednoczesnych użytkowników, przepustowość systemu spadnie jeszcze bardziej, a wpływ aplikacji będzie większy.

Zmiany danych są zapisywane w pliku dziennika, podobnie jak blokady, które je chronią. Nie można ich usunąć z dziennika, dopóki transakcja nie zostanie zatwierdzona. Dlatego bardzo długa transakcja może powodować wzdęcie pliku dziennika i związane z tym problemy.

Jeśli bieżąca praca korzysta z tempdb, co jest prawdopodobne w przypadku dużych obciążeń, zasoby mogą być powiązane do końca transakcji. W skrajnych przypadkach może to spowodować niepowodzenie innych zadań, ponieważ nie ma już dla nich wystarczającej ilości miejsca. Miałem przypadki, w których źle zakodowane UPDATE wypełnione tempdb, więc brakowało dysku na SORT raportu i raport nie powiódł się.

Jeśli wybierzesz ODWRÓCENIE transakcji lub system zawiedzie i odzyska, czas potrzebny na ponowne udostępnienie systemu będzie zależał od ilości wykonanej pracy. Samo otwarcie transakcji nie wpłynie na czas odzyskiwania, to ile pracy zostało wykonane. Jeśli transakcja była otwarta, ale bezczynna przez godzinę, powrót do zdrowia będzie prawie natychmiastowy. Jeśli pisał nieprzerwanie dla tej godziny, podstawową zasadą jest to, że czas powrotu do zdrowia wyniesie około godziny.

Jak widać, długa transakcja może być problematyczna. W przypadku systemów OLTP najlepszą praktyką jest posiadanie jednej transakcji bazy danych na transakcję biznesową. Do pracy wsadowej wprowadzaj proces w blokach, z częstymi zatwierdzeniami i ponownie uruchom kodowanie logiczne. Zazwyczaj w ramach jednej transakcji DB można przetworzyć kilka tysięcy rekordów, ale należy to przetestować pod kątem współbieżności i zużycia resoruce.

Nie kusz się, aby przejść do drugiej skrajności i całkowicie unikać transakcji i blokad. Jeśli chcesz zachować spójność swoich danych (i dlaczego miałbyś korzystać z bazy danych?) Poziomy izolacji i transakcje mają bardzo ważny cel. Dowiedz się o swoich opcjach i zdecyduj, z jaką równowagą współbieżności i poprawności jesteś przygotowany do życia dla każdej części aplikacji.

Michael Green
źródło
nawet jeśli jest otwarty przez trzy dni?
JanLeeYu
Tak, nawet przez trzy dni. Ważną kwestią jest ilość pracy, która została wykonana, gdy TX jest otwarty, a nie tylko jak długo był otwarty. Oczywiście jako DBA możesz zapytać właściciela transakcji, dlaczego potrzebuje go tak długo. Kiedy prowadziłem zespół DBA, zarejestrowałem wszystkie TX, które były otwarte przez ponad 30 minut i rozmawiałem z właścicielem.
Michael Green
DOBRZE. Dzięki za świetne wyjaśnienie. Chociaż wszyscy też świetnie sobie radzili.
JanLeeYu
Co za ulga ... Jeszcze raz dziękuję za odpowiedź.
JanLeeYu
„Źle zakodowana AKTUALIZACJA” Tak. Widzieć to. Instrukcja aktualizacji wewnątrz pętli, która nie zakwalifikowała niektórych nazw i spowodowała zachowanie podobne do 1 = 1, więc aktualizowała całą tabelę dla każdej iteracji pętli (która również umieszczała nieprawidłowe dane w większości tych wierszy).
jpmc26
6

Waszą największą konsekwencją będzie blokowanie obiektów użytych w transakcji. Zwłaszcza jeśli zakładasz, że użytkownicy wstawiają dane, wówczas ta długotrwała transakcja może zawierać instrukcje SELECT w często używanych tabelach. Instrukcje aktualizacji użytkowników mogą nie być w stanie uzyskać niezbędnej blokady wymaganej do ukończenia aktualizacji lub wstawień.

Drugą rzeczą, która może się zdarzyć, jest aktywność pliku dziennika, powiedzmy, że jeśli aktualizujesz duży zestaw danych, część dziennika, z której korzysta transakcja, pozostaje aktywna przez czas trwania tej transakcji. Nie będzie można ponownie użyć tej części dziennika, dopóki transakcja nie zostanie zatwierdzona lub wycofana. W scenariuszach, w których możesz być w bardzo aktywnym systemie OLTP, może to spowodować szybki wzrost pliku dziennika i zapełnienie urządzenia pamięci masowej.

Andriy M.
źródło
na przykład ten, który utworzył transakcję, jest odłączony od serwera, czy będzie mógł ponownie zalogować się na serwerze, aby zamknąć transakcję?
JanLeeYu
Będzie to zależeć, jeśli transakcja odbyła się w środowisku wykorzystującym MSDTC, może to być transakcja osierocona. W takim przypadku żaden użytkownik nie byłby już w stanie sam go zamknąć ... DBA musiałby wkroczyć, aby go obsłużyć. Poza tym generalnie transakcja powinna zostać anulowana przez SQL Server po rozłączeniu ... ale znowu w przypadku dużych transakcji, które mogą nie mieć miejsca za każdym razem.
W takim przypadku, czy administrator nadal będzie w stanie zamknąć transakcję?
JanLeeYu
Nie mogę na to odpowiedzieć, wszystko zależy. Miałem przypadki, w których serwer musiał zostać zrestartowany lub instancja nie przeszła do węzła dodatkowego / repliki.
4

Niekompletna transakcja może zawierać dużą liczbę blokad i powodować blokowanie

Jeśli transakcja nie zostanie zakończona z powodu przekroczenia limitu czasu zapytania lub z powodu anulowania partii w środku transakcji bez wydawania instrukcji COMMIT lub ROLLBACK w celu sfinalizowania transakcji, transakcja pozostaje otwarta, a wszystkie blokady uzyskane podczas tej transakcji są kontynuowane które odbędzie się. Kolejne transakcje wykonane w ramach tego samego połączenia są traktowane jako transakcje zagnieżdżone, więc wszystkie blokady nabyte w tych zakończonych transakcjach nie są zwalniane. Ten problem powtarza się przy wszystkich transakcjach wykonanych z tego samego połączenia, aż do wykonania operacji ROLLBACK. W rezultacie utrzymywana jest duża liczba blokad, użytkownicy są blokowani, a transakcje tracone, co powoduje, że dane są inne niż się spodziewano.

źródło

Pimp Juice IT
źródło
na przykład ten, który utworzył transakcję, jest odłączony od serwera, czy będzie mógł ponownie zalogować się na serwerze, aby zamknąć transakcję?
JanLeeYu
Gdy SQL Server dowie się, że połączenie zostało utracone, wycofuje transakcję. Zobacz tutaj dba.stackexchange.com/questions/47404/… . Jeśli ten sam użytkownik ponownie się połączy, będzie to inna sesja, więc nie może jakoś „przyjąć” starej transakcji.
Michael Green,