Odpowiedzi:
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_TRANSACTIONS
jest OFF
i wyraźnie określić, begin tran
a commit/rollback
następnie ten jest powszechnie znany jako jawnej transakcji . W przeciwnym razie otrzymasz transakcję automatycznego zatwierdzania.
Kiedy IMPLICIT_TRANSACTIONS
jest 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)ON
SELECT
UPDATE
CREATE
BEGIN 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 .
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:
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)
IMPLICIT & Transakcja jawna:
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.
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ą.
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.
BEGIN TRAN SELECT ... COMMIT
vs właśnieSELECT
tam wydaje się, że jest bardzo niewielka różnica wydajności.