Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

5. Dezember 2007 um 19:17

Blockierungen bei Updates auf unterschiedlichen Datensätzen

Die Frage lautete:

Auf Verbindung 1 wird in einer etwas längeren Transaktion (ja, macht man nicht, aber nur mal angenommen..) der Datensatz mit ID "0815″ geändert.

Auf Verbindung 2 wird jetzt ein UPDATE-Befehl auf den Datensatz mit der ID "4711″ abgesetzt (… WHERE ID = 4711).

Geht der UPDATE auf der Verbindung 2 glatt durch oder wird er von Verbindung 1 blockiert?

Das kommt darauf an….

Tabelle ohne Index

Gehen wir mal davon aus, die Tabelle ist ein Heap, also eine Tabelle ohne Clustered Index, außerdem sind gar keine Indexes darauf. Dann muss der SQL-Server wohl oder übel einen Table-Scan durchführen um die betroffenen Sätze zu finden. Dazu liest er jeden Satz durch. Auf den gerade untersuchten Satz wird eine Update-Sperre (U) gesetzt. Ist der Datensatz betroffen, dann wird sie ein eine Exklusiv-Sperre (X) umgewandelt, sonst sofort wieder freigegeben.

Wegen des Table-Scan versucht Verbindung 2 auch den Satz mit ID 0815 zu lesen (er liest alle Sätze der Tabelle). Der ist schon gesperrt, daher wird die Verbindung blockiert. Der zweite muss warten und versteht nicht warum… 😉

Der SQL-Server-2005 verwendet hier übrigens Satz-Sperren, während der 2000er generell beim Table-Scan Seitensperren verwendete. In den anderen unten genannten Fällen verhalten sich die Systeme gleich.

Tabelle mit Index

Hat die Tabelle einen Index auf dem Suchfeld (hier ID), dann sieht es anders aus. Sowohl bei einem Clustered-Index als auch einem normalen Index kann der SQL-Server den Datensatz direkt mittels Index-Seek anspringen.

Daher tritt hier keine Blockierung auf.

Tabelle mit Index, Suche über zwei Felder

Angenommen wir filtern nicht über die ID, sondern über zwei Felder, z.B. Kundennummer und laufende-Nummer (… WHERE KDNR=4711 AND LFDNR=10). Nur auf einem davon ist ein Index: Auf der Kundennummer liegt ein nicht-eindeutiger Index, pro Kundennummer kann es zig laufende Nummern geben.

Dann macht der SQL-Server zwar einen Index-Seek auf alle Sätze mit KDNR=4711, aber er muss für alle potentiell betroffenen Sätze nachsehen, welchen Wert LFDNR hat. Daher wird auch hier eine Blockierung auftreten, wenn zufällig ein anderer Satz mit der gleichen Kundennummer schon exklusiv gesperrt ist.

Resümee

Ob es bei zwei UPDATEs auf unterschiedlichen Datensätzen zu einer Blockierung kommt oder nicht, hängt ganz allein vom Zugriffsplan des "Zweiten" ab. Der Nutzen der richtigen Indexe kann gar nicht hoch genug bewertet werden.

Und wie schon Cato sagte: Transaktionen müssen immer so kurz wie möglich sein.

Ausschlussklauseln

  • Das Geschriebene gilt auch für DELETEs.
  • Man kann die Blockierung nicht wirklich umgehen. Man kann lediglich mittels READPAST angeben, dass gesperrte Datensätze übersprungen werden. Das macht aber wirklich nur dann Sinn, wenn es wirklich egal ist, ob alle vom UPDATE oder DELETE betroffenen Datensätze geändert werden.
  • Wenn man den Isolation-Level "SNAPSHOT" verwendet, dann könnte es anders sein, das habe ich nicht ausprobiert.
  • Wenn man SERIALIZABLE verwendet, dann ist es ähnlich nur schlimmer, weil dann jede Menge RangeS-U-Locks gesetzt werden. Aber wann macht man schon SERIALIZABLE bei UPDATEs oder DELETEs?
5. Dezember 2007 um 19:15

Buch über "Visual Basic 2005" zum Download

Derzeit gibt es das Buch "Microsoft Visual Basic 2005 – Das Entwicklerbuch" von Klaus Löffelmann bei Microsoft zum kostenlosen Download: Teil 1 jetzt, TEil 2 kommt in zwei Wochen. Es kostet im Microsoft Press Shop aktuell stolze 59 Euro.

Ich werde mal reinschauen. Meine Tochte mochte gerne lernen, wie man selber Spiele programmiert und ich ringe mit mir, was ich ihr beibringe: C# oder VB. C# kann ich ganz gut, aber VB soll leichter sein (was ich aber erst mal selber lernen müsste). Vielleicht hilft mir das Buch bei der Entscheidung.

via MSDN Flash 25/2007
5. Dezember 2007 um 19:03

Gulp bleibt Gulp

Als Kind las ich sehr gerne die Walt-Disney-Taschenbücher. Dort machte Donald immer dann "GULP", wenn er schwer schlucken musste, weil ihm etwas Schlimmes bevorstand. Heute ist das vermutlich nicht mehr so, denn heute heisst eine Firma "Gulp". Die Firma wurde verkauft und deswegen bekam ich eine Mail, die so endete (Name entfernt):

Fazit: GULP bleibt GULP. In diesem Sinne freue ich mich auf die weitere
erfolgreiche Zusammenarbeit mit Ihrem Hause.

Vielen Dank und beste Grüße.

K… T…..<http://www.gulp.de/mailings/images/ct_unterschrift.jpg>

Wenn man unter der angegebenen Mailadresse nachschaut, dann sieht man tatsächlich die Unterschrift des Absenders. Das haut mich total von den Socken. Der Absender riskiert damit, dass jemand mit einfachsten Mitteln Dokumente mit seiner Unterschrift produziert. Wenn er sie dann auch noch faxt, dann kann der Empfänger zunächst mal nicht feststellen, dass es sich um eine Fälschung handelt! Da würde ich auch "GULP" machen… 😉

Oder kann man bei solchen Gelegenheiten (also öffentlich im Internet) so unterschreiben, dass das nicht als geschäftsfähige Unterschrift gilt, z.B. indem man das Ende des Namens sehr undeutlich schreibt?

|