Czy zawsze jest to zła praktyka?

88

Czy zawsze jest to zła praktyka?

Na przykład, dobrą praktyką jest tworzenie transakcji tylko dla jednej prostej SELECT?

Jaki jest koszt utworzenia transakcji, gdy nie jest to naprawdę konieczne?

Nawet jeśli używasz poziomu izolacji READ UNCOMMITTED, czy to zła praktyka?

Elranu
źródło
1
Patrząc na wpływ BEGIN TRAN SELECT ... COMMITvs właśnie SELECTtam wydaje się, że jest bardzo niewielka różnica wydajności.
Martin Smith

Odpowiedzi:

100

Czy zawsze złą praktyką jest tworzenie transakcji?

To zależy od kontekstu, o którym tu mówisz. Jeśli jest to aktualizacja, zdecydowanie polecam jawne użycie TRANSAKCJI. Jeśli jest to WYBÓR, to NIE (jawnie).

Ale poczekaj, najpierw musisz zrozumieć: wszystko na serwerze SQL jest zawarte w transakcji.

Gdy opcja sesja IMPLICIT_TRANSACTIONSjest OFFi wyraźnie określić, begin trana commit/rollbacknastępnie ten jest powszechnie znany jako jawnej transakcji . W przeciwnym razie otrzymasz transakcję automatycznego zatwierdzania.

Kiedy IMPLICIT_TRANSACTIONSjest transakcja niejawna jest uruchamiany automatycznie podczas wykonywania jednego z rodzajów rachunku udokumentowane w księgach artykule online (np / / ) i musi być popełnione jawnie lub wycofana. Wykonanie w tym trybie spowoduje zwiększenie i rozpoczęcie kolejnej „zagnieżdżonej” transakcji)ONSELECTUPDATECREATEBEGIN TRAN@@TRANCOUNT

Aby zmienić tryb, w którym się znajdujesz, możesz użyć

SET IMPLICIT_TRANSACTIONS ON

lub

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

jeśli powyżej zwraca 2, jesteś w trybie transakcji niejawnych. Jeśli zwróci 0, jesteś w automatycznym zatwierdzaniu.

ile kosztuje utworzenie transakcji, gdy nie jest to naprawdę konieczne?

Potrzebne są transakcje, aby przenieść bazę danych z jednego spójnego stanu do innego spójnego. Transakcje nie wiążą się z żadnymi kosztami, ponieważ nie ma alternatywy dla transakcji. Patrz: Korzystanie z poziomów izolacji opartych na wersjach wierszy

Nawet jeśli używasz poziomu izolacji read_uncomitted. Czy zła praktyka? ponieważ nie powinno mieć problemów z blokowaniem.

Poziom izolacji READ_UNCOMMITED pozwoli z definicji na brudne odczyty, tzn. Jedna transakcja będzie mogła zobaczyć niezatwierdzone zmiany dokonane przez inną transakcję. To, co robi ten poziom izolacji, odciąża nadmiar blokowania - metodę uzyskiwania blokad w celu ochrony współbieżności bazy danych.

Możesz użyć tego na poziomie połączenia / zapytania, aby nie miało to wpływu na inne zapytania.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Znalazłem interesujący artykuł Jeffa Atwooda opisujący Deadlocks z powodu Puzzle Philosophers Puzzle oraz opisujący poziom izolacji popełnionego zdjęcia migawkowego .

EDYTOWAĆ:

Z ciekawości wykonałem test mierzący wpływ na dziennik T za pomocą liczników Perfmon, takich jak Log Bytes Flushed / Sec, Log Flush Waits / Sec (Liczba zatwierdzeń na sekundę, które czekają na wystąpienie loga), jak na poniższym wykresie:

wprowadź opis zdjęcia tutaj

przykładowy kod :

create table testTran (id int, Name varchar(8))
go

-- 19 sec
-- Autocommit transaction
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
---------------------------------------------------
-- 2 sec
-- Implicit transaction
SET IMPLICIT_TRANSACTIONS ON
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
COMMIT;
SET IMPLICIT_TRANSACTIONS OFF


----------------------------------------------------
-- 2 sec
-- Explicit transaction
declare @i int
set @i = 0
BEGIN TRAN
WHILE @i < 100000
Begin
INSERT INTO testTran values (1,'Kin Shah')
set @i = @i+1
End
COMMIT TRAN

Transakcje z automatycznym zatwierdzeniem : (Edytowane jako wyróżnione przez @TravisGan)

  • Wkładka zajęła 19 sekund.
  • Każdy Autocommit opróżni bufor T-log na dysk z powodu autocomit (po podświetleniu @TravisGan, a ja o tym wspomniałem).
  • Proces CHECKPOINT kończy się szybko, ponieważ ilość zabrudzonego buforu dziennika wymaganego do opróżnienia będzie mniejsza, ponieważ często pracuje cicho.

IMPLICIT & Transakcja jawna:

  • Wkładka zajęła 2 sekundy.
  • W przypadku transakcji EXPLICIT bufory dziennika zostaną opróżnione tylko wtedy, gdy są pełne.
  • W przeciwieństwie do transakcji Autocommit, w transakcji EXPLICIT proces CHECKPOINT potrwa dłużej, ponieważ będzie miał więcej buforów dziennika do opróżnienia (pamiętaj, że bufory dziennika są opróżniane tylko wtedy, gdy są pełne).

Istnieje DMV sys.dm_tran_database_transactions , które zwracają informacje o transakcjach na poziomie bazy danych.

Oczywiście jest to bardziej uproszczony test pokazujący wpływ. Wpływ będą miały również inne czynniki, takie jak podsystem dysku, ustawienia automatycznego wzrostu bazy danych, początkowy rozmiar bazy danych, inne procesy uruchomione na tym samym serwerze \ baza danych itp.

Z powyższych testów nie ma prawie żadnej różnicy między transakcjami niejawnymi i jawnymi.

Dzięki @TravisGan za pomoc w dodaniu więcej do odpowiedzi.

Kin Shah
źródło
35

Instrukcja SQL zawsze działa w transakcji. Jeśli nie uruchomisz go jawnie, każda instrukcja SQL będzie działać jako transakcja sama w sobie.

Jedynym wyborem jest to, czy do jednej transakcji zostanie dołączonych wiele wyciągów. Transakcje obejmujące wiele instrukcji pozostawiają blokady, które szkodzą współbieżności. Dlatego „zawsze” tworzenie transakcji nie jest dobrym pomysłem. Powinieneś zrównoważyć koszt z korzyścią.

Andomar
źródło
1

Problem polega na tym, czy grupę operacji należy traktować jako pojedyncze działanie. Innymi słowy, wszystkie operacje muszą zostać zakończone i zatwierdzone pomyślnie lub żadna z operacji nie może zostać zatwierdzona. Jeśli masz scenariusz, który wymaga odczytania danych wstępnych, a następnie wykonania aktualizacji na podstawie tych danych, początkowy odczyt prawdopodobnie powinien być częścią transakcji. Uwaga: celowo unikam Select / Insert / Update. Zakres transakcji może faktycznie znajdować się na poziomie aplikacji i obejmować wiele operacji na bazie danych. Pomyśl o klasycznych wzorach, takich jak rezerwacja miejsca w samolocie lub zapytanie / wycofanie salda bankowego. Należy spojrzeć na problem z szerszej perspektywy, aby zapewnić, że cała aplikacja zapewnia wiarygodne, spójne dane.

Promień
źródło