Ist es eine schlechte Praxis, immer eine Transaktion zu erstellen?

88

Ist es eine schlechte Praxis, immer eine Transaktion zu erstellen?

Es empfiehlt sich beispielsweise, eine Transaktion nur für eine einfache Transaktion zu erstellen SELECT.

Was kostet das Erstellen einer Transaktion, wenn es nicht wirklich notwendig ist?

Auch wenn Sie eine Isolationsstufe wie verwenden READ UNCOMMITTED, ist es eine schlechte Praxis?

Elranu
quelle
1
Betrachtet man die Auswirkung von BEGIN TRAN SELECT ... COMMITvs, so SELECTscheint es einen äußerst geringen Leistungsunterschied zu geben.
Martin Smith

Antworten:

100

Ist es immer eine schlechte Praxis, eine Transaktion zu erstellen?

Es hängt davon ab, über welchen Kontext Sie hier sprechen. Wenn es sich um ein Update handelt, kann ich die Verwendung von TRANSACTIONS ausdrücklich empfehlen. Wenn es ein SELECT ist, dann NO (explizit).

Aber warten Sie, es gibt mehr zu verstehen: Alles in SQL Server ist in einer Transaktion enthalten.

Wenn die Sitzung Option IMPLICIT_TRANSACTIONSist OFFund Sie explizit angeben , begin tranund commit/rollbackdann wird dies allgemein als bekannt explizite Transaktion . Andernfalls erhalten Sie eine Autocommit-Transaktion.

Wenn IMPLICIT_TRANSACTIONSwird ONeine implizite Transaktion wird automatisch gestartet , wenn eine der Anweisungstypen dokumentierten in den Bücher Online - Artikel Ausführung (zB SELECT/ UPDATE/ CREATE) und es muss wieder ausdrücklich verpflichtet oder gerollt werden. Das Ausführen von BEGIN TRANin diesem Modus würde eine @@TRANCOUNTweitere "verschachtelte" Transaktion inkrementieren und starten.)

Um zu wechseln, in welchem ​​Modus Sie sich befinden, verwenden Sie

SET IMPLICIT_TRANSACTIONS ON

oder

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

Wenn oben 2 zurückgegeben wird, befinden Sie sich im impliziten Transaktionsmodus. Wenn es 0 zurückgibt, werden Sie automatisch festgeschrieben.

Wie hoch sind die Kosten für die Erstellung einer Transaktion, wenn dies nicht wirklich erforderlich ist?

Transaktionen sind erforderlich, um die Datenbank von einem konsistenten Zustand in einen anderen konsistenten Zustand zu versetzen. Transaktionen sind kostenlos, da es keine Alternative zu Transaktionen gibt. Siehe: Verwenden von zeilenversionsbasierten Isolationsstufen

Auch wenn Sie eine Isolationsstufe verwenden read_uncomitted. Ist eine schlechte Praxis? weil es keine Probleme mit dem Sperren haben sollte.

Die Isolationsstufe READ_UNCOMMITED ermöglicht per Definition Dirty Reads, dh eine Transaktion kann nicht festgeschriebene Änderungen sehen, die von einer anderen Transaktion vorgenommen wurden. Diese Isolationsstufe lockert den Overhead des Sperrens - eine Methode zum Abrufen von Sperren zum Schutz der gleichzeitigen Verwendung von Datenbanken.

Sie können dies auf Verbindungs- / Abfrageebene verwenden, sodass andere Abfragen davon nicht betroffen sind.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Es wurde ein interessanter Artikel von Jeff Atwood gefunden, der Deadlocks aufgrund von Dining Philosophers Puzzle beschreibt und die von Lesern festgelegte Snapshot- Isolationsstufe beschreibt.

BEARBEITEN:

Aus Neugier habe ich einige Tests durchgeführt, um die Auswirkung auf T-Log mit Perfmon-Zählern wie Log Bytes Flushed / Sek., Log Flush Waits / Sek. (Anzahl der Commits pro Sek., Die darauf warten, dass LOG Flush ausgeführt wird) zu messen.

Bildbeschreibung hier eingeben

Beispielcode :

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

Transaktionen automatisch festschreiben : (Bearbeitet wie von @TravisGan hervorgehoben)

  • Einfügen dauerte 19 Sekunden.
  • Bei jedem Autocommit wird der T-Log-Puffer aufgrund von Autocomit auf die Festplatte gespült (nachdem @TravisGan markiert wurde und ich dies nicht erwähnt habe).
  • Der CHECKPOINT-Prozess wird schnell abgeschlossen, da der zum Löschen erforderliche Puffer für verschmutzte Protokolle geringer ist, da er häufig leise ausgeführt wird.

IMPLICIT & Explicit Transaction:

  • Einfügen dauerte 2 Sekunden.
  • Bei einer EXPLICIT-Transaktion werden die Protokollpuffer nur geleert, wenn sie voll sind.
  • Im Gegensatz zur Autocommit-Transaktion dauert der CHECKPOINT-Vorgang in der EXPLICIT-Transaktion länger, da mehr Protokollpuffer gelöscht werden müssen (denken Sie daran, dass Protokollpuffer nur dann gelöscht werden, wenn sie voll sind).

Es gibt eine DMV sys.dm_tran_database_transactions , die Informationen zu Transaktionen auf Datenbankebene zurückgibt .

Offensichtlich ist dies eher ein simpler Test, um die Auswirkungen zu zeigen. Andere Faktoren wie das Festplattensubsystem, die Einstellungen für das automatische Datenbankwachstum, die anfängliche Größe der Datenbank, andere Prozesse, die auf demselben Server ausgeführt werden, haben ebenfalls Einfluss.

Aus den obigen Tests ergibt sich nahezu kein Unterschied zwischen impliziten und expliziten Transaktionen.

Vielen Dank an @TravisGan, dass Sie dazu beigetragen haben, der Antwort mehr hinzuzufügen.

Kin Shah
quelle
35

Eine SQL-Anweisung wird immer in einer Transaktion ausgeführt. Wenn Sie keine explizite Anweisung starten, wird jede SQL-Anweisung in einer eigenen Transaktion ausgeführt.

Die einzige Wahl ist, ob Sie mehrere Anweisungen in einer Transaktion bündeln. Transaktionen, die mehrere Anweisungen umfassen, hinterlassen Sperren, die die Parallelität beeinträchtigen. Es ist also keine gute Idee, "immer" Transaktionen zu erstellen. Sie sollten die Kosten gegen den Nutzen abwägen.

Andomar
quelle
1

Die Frage ist, ob eine Gruppe von Operationen als eine einzige Aktion behandelt werden muss. Mit anderen Worten, alle Vorgänge müssen erfolgreich abgeschlossen und festgeschrieben werden, sonst kann keiner der Vorgänge festgeschrieben werden. Wenn Sie ein Szenario haben, in dem Sie vorläufige Daten lesen und dann Aktualisierungen basierend auf diesen Daten durchführen müssen, sollte der erste Lesevorgang wahrscheinlich Teil der Transaktion sein. Hinweis: Ich vermeide das absichtliche Auswählen / Einfügen / Aktualisieren. Der Transaktionsbereich kann sich tatsächlich auf Anwendungsebene befinden und mehrere Datenbankoperationen umfassen. Denken Sie an klassische Muster wie Sitzplatzreservierung im Flugzeug oder Kontostandabfrage / -bezug. Man muss das Problem genauer betrachten, um sicherzustellen, dass die gesamte Anwendung zuverlässige, konsistente Daten liefert.

Strahl
quelle