Wie ist die genaue Beziehung zwischen einer Datenbanktransaktion und dem Sperren?

16

Dies ist eine bescheidene Frage, die gestellt wird, um mein Wissen zu erweitern. Sei freundlich in deiner Antwort.

Als langjähriger Anwendungsentwickler weiß ich auf einer bestimmten Ebene, was eine Transaktion ist (ich verwende sie die ganze Zeit). Abgesehen von den Isolationsstufen für Transaktionen kann ein Arbeitsblock auf hoher Ebene vollständig oder gar nicht abgeschlossen werden, und es ist ein gewisses Maß an Isolation von anderen datenbankmodifizierenden Aktivitäten möglich.

Ich weiß auch, was (in verschiedenen Datenbanken) eine Sperre ist oder zumindest, wie sich eine Sperre verhält (wenn ich eine Tabelle explizit sperre, kann kein anderer Prozess oder Thread etwas über diese Tabelle aktualisieren).

Was mir am deutlichsten nicht klar ist: Wenn ich in verschiedenen Datenbanken explizit eine Zeile oder eine Tabelle sperre, verwende ich genau dieselben Konstrukte, die von den Transaktionseinrichtungen der Datenbank unter der Deckung verwendet werden, damit die Transaktion ordnungsgemäß funktioniert?

Das heißt, es fällt mir ein, dass eine Transaktion, um atomar und isoliert zu sein, eine Sperrung durchführen muss. Handelt es sich bei diesem transaktionsinitiierten, durch Transaktion verborgenen Sperren um dieselbe Art von Sperren, auf die ich mithilfe von Konstrukten wie SELECT FOR UPDATEoder expliziten LOCKBefehlen aus verschiedenen Datenbanken zugreifen kann ? Oder sind diese beiden Konzepte völlig unterschiedlich?

Wieder entschuldige ich mich für die Naivität dieser Frage; Ich freue mich, auf weitere grundlegende Quellen hingewiesen zu werden.

Laird Nelson
quelle

Antworten:

12

Wenn ich eine Zeile oder eine Tabelle explizit sperre, verwende ich genau dieselben Konstrukte, die von den Transaktionseinrichtungen der Datenbank im Hintergrund verwendet werden, damit die Transaktion ordnungsgemäß funktioniert?

Ja. Wenn dies nicht der Fall wäre, würde Ihre eigene "Verriegelung" nur für andere ähnliche "Verriegelungen" gelten und nicht mit der motoreneigenen Verriegelung interagieren. Sie würden also eine Zeile in einer Tabelle sperren, damit sie nicht auf die gleiche Weise von einer anderen Anwendung gesperrt werden kann, aber Ihre Sperre würde von der Engine selbst ignoriert. Diese Semantik wird selten gewünscht. In den meisten Fällen bedeutet eine Anwendung, die eine Zeile sperrt, 'sie gegen alle Arten des Zugriffs / der Änderung sperren'. Seite zur Kenntnis , dass Verriegelungsmechanismen , die streng anwendungsspezifischen tun vorhanden ist , weil sie nützlich sind. Beispielsweise verfügt SQL Server über Anwendungssperren .

Damit eine Transaktion atomar und isoliert ist, muss sie gesperrt werden.

Verriegelung ist ein Mittel, um dies zu erreichen. Die Hauptalternative ist die Versionierung. Heutzutage unterstützen die meisten Datenbanken beides (was auch bedeutet, dass, wenn Sie eine Zeile in der App sperren, aber eine andere Transaktion zum Lesen der Zeile die Versionierung verwendet, diese gelesen wird, da Ihre Sperre versionierte Lesevorgänge nicht blockiert).

Sie kreisen sozusagen um ein Konzept, das in der Welt der Datenbankimplementierung als "Two Phase Locking Protocol" bekannt ist . Der verlinkte Wikipedia-Artikel ist ein guter Anfang. Wenn Sie ausführlichere Erklärungen zu diesem Thema lesen möchten, empfehle ich, in die Bibliothek zu gehen und eine Ausleihe über die Transaktionsverarbeitung: Konzepte und Techniken anzufordern . Nahezu jede Datenbank ist im Kern eine Implementierung dieses Buches.

Remus Rusanu
quelle
Vielleicht können Sie über die (nicht sperrende) optimistische Parallelitätskontrolle
ypercubeᵀᴹ
Aha! Jetzt reden wir. In der Tat lauerte MVCC im Hinterkopf . Vielen Dank für die gut formulierte Antwort, die tollen Referenzen und dass Sie sich die Zeit genommen haben, sich wirklich mit meiner Frage zu befassen.
Laird Nelson
3

Einige Hintergrundinformationen, bevor Sie Ihre Fragen beantworten:

Hinweis: Dies bezieht sich auf Microsoft SQL Server - RDBMS ........

  • In sehr einfachen Worten ist eine Transaktion eine Folge von Arbeiten, die als eine einzige logische Einheit in ihrer Gesamtheit ausgeführt werden müssen und die ACID-Eigenschaften beibehalten müssen.
  • Jedes RDBMS muss "Sperrfunktionen" bereitstellen, mit denen die Transaktion in ihrer Gesamtheit abgeschlossen werden kann, indem die Transaktionsisolation und ihre Beständigkeit beibehalten werden. Dies stellt die physische Integrität der Datenbank sicher.
  • Am wichtigsten ist jedoch, dass Transaktionen standardmäßig auf Verbindungsebene verwaltet werden. Wenn also eine Transaktion für eine Verbindung gestartet wird, sind alle T-SQL-Anweisungen (S / I / U / D), die für diese Verbindung ausgeführt werden, Teil der Transaktion, bis die Transaktion endet. ( MARS wird anders behandelt)

Nun zurück zu deinen Fragen:

Wenn ich eine Zeile oder eine Tabelle explizit sperre, verwende ich genau dieselben Konstrukte, die von den Transaktionseinrichtungen der Datenbank im Hintergrund verwendet werden, damit die Transaktion ordnungsgemäß funktioniert?

Ja. Dies bedeutet, dass Sie die Reihenfolge der Daten, die geändert werden und die die Datenbank in einem konsistenten Zustand belassen, sorgfältig festlegen müssen. Mit anderen Worten, Ihre DML-Operation sollte die Datenbank in einem konsistenten Zustand belassen, der sich auf die Geschäftsregeln Ihrer Organisation beschränkt. Dennoch kann das RDBMS (hier SQL Server) die physische Integrität der Transaktion erzwingen.

Über BOL: Sperren und Versionskontrolle verhindern, dass Benutzer nicht festgeschriebene Daten lesen und dass mehrere Benutzer gleichzeitig versuchen, dieselben Daten zu ändern. Ohne Sperren oder Zeilenversionierung können Abfragen, die für diese Daten ausgeführt werden, zu unerwarteten Ergebnissen führen, indem Daten zurückgegeben werden, die noch nicht in der Datenbank festgeschrieben wurden.

Handelt es sich bei diesem transaktionsinitiierten, transaktionsversteckten Sperren um dieselbe Art von Sperren, auf die ich über Konstrukte wie SELECT FOR UPDATE oder explizite LOCK-Befehle zugreifen kann?

Alles in SQL Server ist in einer Transaktion enthalten. Wenn Sie auf Ihre Daten zugreifen, muss das RDBMS abhängig von der Isolationsstufe und den Vorgängen, die Sie für Ihre Daten ausführen, Sperren ausführen. Überprüfen Sie diese Antwort für weitere Details.

Einige gute Referenzen:

Kin Shah
quelle
2

Ich würde sagen, Transaktionen sind in gewissem Sinne Teil der "Schnittstelle" der Datenbank. Sie als Entwickler entscheiden, wann sie beginnen, enden, was im Rahmen von Transaktionen zu tun ist usw. Sperren gehören, wie ich sie sehe, zu den Implementierungsdetails und für die Zugriffssynchronisation auf verschiedene Objekte verwendet. In den meisten Fällen entscheidet der Motor selbst, was und wie lange gesperrt werden soll. Es gibt viele Sperren auf Systemebene, die nicht direkt manipuliert werden können (z. B. kann die Engine bestimmte Speicherbereiche sperren). Selbst wenn es um DML-Sperren geht, geschieht dies häufig im Hintergrund (z. B. um die referenzielle Integrität von Oracle zu gewährleisten. Soweit ich mich erinnere, kann SQLServer eine entsprechende Zeile in der Master-Tabelle sperren, wenn ein neuer Datensatz eingefügt wird Detailtabelle) als Ergebnis von DML-Anweisungen, die innerhalb der Transaktion ausgegeben wurden.

Bei Transaktionen können Sie von jedem RDMS, das behauptet, SQL- und Support-Transaktionen zu erfüllen, ein mehr oder weniger konsistentes Verhalten erwarten. Bei Sperren verwendet jedoch fast jeder Anbieter eine andere Strategie und Terminologie. Der gemeinsame Teil aller RMDS ist, soweit ich das beurteilen kann, dass die Parallelität zwischen Transaktionen durch die Isolationsstufe definiert wird, während die Parallelität zwischen Sperren durch Sperrentypen (gemeinsam genutzt, exklusiv usw.) gesteuert wird.

Zusammenfassend ist festzuhalten, dass Sperren ein Mechanismus auf niedriger Ebene sind, um die Konsistenz von Objekten und die Parallelität zu steuern. Während der Ausführung von SQL-Anweisungen können Sperren ausgegeben werden. Abhängig von der Implementierung der Transaktionsisolationsstufe kann die Engine verschiedene Arten von Sperren für betroffene Objekte festlegen (Zeilen, Zeilengruppen, Indizes usw.). Es ist eine begrenzte Anzahl von Befehlen verfügbar, um Sperren ( SELECT FOR UPDATE, LOCK) manuell auszugeben . DML-Sperren können eskaliert werden (abhängig von RDMS, z. B. in SQLServer row-> page-> partition-> table). Sperren können auch von der Datenbank-Engine während des Verbindungsaufbaus, der Sicherung, Wiederherstellung, Prozedur / Trigger / Funktion / usw. beim Neukompilieren, Starten, Herunterfahren usw. ausgegeben werden.

Ich bin nicht sicher, ob das Ihre Frage beantwortet, aber ich hoffe, dass es Sinn macht.

a1ex07
quelle
Danke für deinen Kommentar. Du bist definitiv der Nächste bis jetzt. Ich versuche immer noch zu sehen, ob Transaktionen immer in Bezug auf die Sperren implementiert werden, die beispielsweise von expliziten LOCKoder SELECT FOR UPDATEAnweisungen oder über einen anderen Mechanismus verwendet werden.
Laird Nelson
Soweit ich weiß, gibt es BEGIN TRANSACTIONselbst keine Sperren. Nach DMLs in der Transaktion werden Sperren angezeigt.
a1ex07
Klarstellung - Ich habe gemeint, dass BEGIN TRANSACTIONselbst keine DML-Sperren erstellt werden. Es sollte tatsächlich einige interne Sperren ausgeben, da es Ressourcen zuweisen, einen Eintrag zur
Systemtabelle
1

Ich werde SQL Server-Jargon verwenden, aber die Konzepte sollten für andere Anbieter gleich sein:

Jeder Befehl, den Sie ausführen, wird innerhalb einer Transaktion ausgeführt. Diese Transaktion kann explizit mit BEGIN TRAN oder implizit vom Datenbankmodul geöffnet werden. Der Grund für das Öffnen einer impliziten Transaktion ist, dass die Engine weiterhin die ACID-Konformität und die Möglichkeit eines Rollbacks gewährleisten muss.

Wenn Sie ein SELECT FOR UPDATE ausführen, bedeutet dies lediglich, dass die Transaktion, während sie ausgeführt wird, eine bestimmte Sperre aufweist.

Matan Yungman
quelle
Danke für deinen Kommentar. Soviel weiß ich. Aber meine Frage ist immer noch: Wenn diese Transaktion geöffnet wird, wird ihre Isolierung durch das Halten eigener Sperren erreicht? Wenn ja, sind diese Sperren die gleichen Arten von Sperren, die ich explizit erwerben kann? Oder wird die Isolation durch die Transaktion auf andere Weise erreicht?
Laird Nelson
2
Ja, das ist der gleiche Mechanismus. Die Isolation wird in beiden Modi durch Sperren erreicht. Dieselben Sperren können Sie explizit erwerben. Der Unterschied besteht darin, dass, wenn Sie eine Transaktion nicht explizit öffnen, die Sperren freigegeben werden, wenn der Befehl beendet ist, wohingegen bei einer expliziten Transaktion die Sperren so lange bestehen bleiben, bis Sie einen Commit ausführen (aufgrund der Isolationsstufen nicht 100% genau, aber das ist der Grund Idee).
Matan Yungman
Danke für deinen Kommentar. Der Grund, warum ich meine Frage stelle, ist, dass ich irgendwo gelesen habe, dass einige Datenbanken MVCC als Mittel zum Erreichen von ACID-Transaktionen verwenden, was meiner Meinung nach eine sperrenfreie Methode ist. In solchen Fällen ist mir nicht klar, wann ich jemals eine Sperre explizit ausstellen möchte. Aber das ist wahrscheinlich eine andere Frage. :-)
Laird Nelson
@LairdNelson ist die Snapshot-Isolationsstufe für SQL Server. Vorhandener, aber nicht der Standardmechanismus für die Parallelität. Dies ist jedoch die Standardeinstellung für Oracle oder Postgresql, IIRC.
Marian
0

Sperre sind notwendig und sie machen die Datenbank. Dies verhindert, dass Daten beschädigt oder ungültig werden, wenn mehrere Benutzer versuchen zu lesen, während andere in die Datenbank schreiben. Die Transaktionsisolation wird normalerweise durch Sperren des Zugriffs auf eine Transaktion implementiert. Schlechte Designanwendungen nutzen das Datenbanksperrkonzept in großem Umfang :) !! Um dies zu vermeiden, konzentrieren Sie sich auf Ihr FK- und Datenlayout.

Es dreht sich alles um SÄURE: - Lies dies und es wird deinen Geist klären! ACID ist eine Reihe von Eigenschaften, die Sie beim Ändern einer Datenbank anwenden möchten.

  • ** Atomizität
  • Konsistenz
  • Isolierung
  • Haltbarkeit**

Eine Transaktion besteht aus einer Reihe verwandter Änderungen, mit denen einige der ACID-Eigenschaften erzielt werden. Transaktionen sind Werkzeuge zum Erreichen der ACID-Eigenschaften.

Atomicity bedeutet, dass Sie garantieren können, dass eine Transaktion vollständig oder gar nicht stattfindet. Sie können komplexe Vorgänge als eine einzige Einheit ausführen, alles oder nichts, und ein Absturz, ein Stromausfall, ein Fehler oder etwas anderes führt dazu, dass Sie sich nicht in einem Zustand befinden, in dem nur einige der damit verbundenen Änderungen stattgefunden haben.

Konsistenz bedeutet, dass Sie garantieren, dass Ihre Daten konsistent sind. Keine der Einschränkungen, die Sie für verwandte Daten haben, wird jemals verletzt.

Isolation bedeutet, dass eine Transaktion keine Daten aus einer anderen Transaktion lesen kann, die noch nicht abgeschlossen ist. Wenn zwei Transaktionen gleichzeitig ausgeführt werden, sieht jeder die Welt so, als würden sie nacheinander ausgeführt, und wenn einer Daten lesen muss, die von einem anderen geschrieben wurden, muss er warten, bis der andere abgeschlossen ist.

Haltbarkeit bedeutet, dass nach Abschluss einer Transaktion garantiert wird, dass alle Änderungen auf einem dauerhaften Medium (z. B. einer Festplatte) aufgezeichnet wurden, und dass die Transaktion ebenfalls abgeschlossen wurde.

Transaktionen sind also ein Mechanismus, um diese Eigenschaften zu garantieren. Sie sind eine Möglichkeit, verwandte Aktionen zu gruppieren, sodass eine Gruppe von Operationen als Ganzes atomar sein, konsistente Ergebnisse liefern, von anderen Operationen isoliert und dauerhaft aufgezeichnet werden kann.

Up_One
quelle
Vielen Dank für Ihren Kommentar. Mir sind die Eigenschaften von ACID zumindest einigermaßen bekannt. Was mir immer noch nicht klar ist: Implementieren Transaktionen ACID mit denselben Sperren, die ich direkt über explizite LOCKAnweisungen verwenden kann, oder tun sie dies mit einem anderen Mechanismus?
Laird Nelson
Datenbanken bieten eine Reihe von Transaktionsisolationsstufen, die den Grad der Sperrung steuern, der bei der Auswahl von Daten auftritt. Serialisierbare, wiederholbare Lesevorgänge, festgeschriebene Lesevorgänge, nicht festgeschriebene Lesevorgänge.
Up_One