Laden...

Transaktions-Deadlock in SQL Server 2008

Letzter Beitrag vor 13 Jahren 10 Posts 9.049 Views
Transaktions-Deadlock in SQL Server 2008

Hi.

Ich habe aktuell ein Problem mit Deadlocks in Transaktionen bei einem verteilten System. Das Programm läuft auf mehreren Rechnern, welche Parallel auf eine DB zugreifen. Konkret kommt folgende Meldung:

System.Data.SqlClient.SqlException: Die Transaktion (Prozess-ID 90) befand sich auf Sperre Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus. 

Prinzipiell dauern Transaktionen max. 5 Sekunden und dann ist das schon sehr lange! Auch die Reihenfolge, wie auf Daten zugegriffen wird, ist im Prinzip überall gleich. Wie kriegt man raus, wo der Deadlock passiert? Leider ist das Phänomen viel zu unregelmäßig (1-2x am Tag bei 20 PCs), als dass mans direkt debuggen kann. Ich schreibe schon die SQL-Kommandos mit, aber es tritt immer woanders auf. Außerdem krig ich so ja nicht die Gegenstelle raus, die am Lock beteiligt ist. Der IsolationLevel ist übrigens auf "ReadUncommitted" gesetzt, was die Auftrittswahrscheinlichkeit schon minimiert hat.

Hat vielleicht irgendwer so ein Problem mal gehabt und ein Lösungsansatz?

Lars

Hey,

jetzt wird es spannend.
Welche Edition des MSSQL hast du ?
Schon mal mit dem "WITH" beschäftigt?
Du kannst du feststellen auf welchen Prozess gewartet wird und dir dort das SQL anschauen + deins.
So kann man dir nicht helfen. Mehr Details bitte.

Das Leben ist schön!

Also Editionen haben wir Express und Developer im Einsatz, tritt bei beiden auf. WITH kenn ich in der Tat nicht im Zusammenhang mit Transaktionsüberwachung ... nur bei temporären Tabellen oder Alter user xxx with xxx. 😉 Hast du ein Link zur MSDN? Mehr als http://msdn.microsoft.com/de-de/library/ms175972.aspx habe ich zu dem Wort nicht gefunden.

Transaktionen sind echt kompliziert, hät ich nicht gedacht. ^^

Hm, mehr Details, weiß gar nicht was ich mehr schreiben sollte. grübel Sämtliche speicheroperationen laufen halt über Transaktionen (System.Data.SqlClient.SqlTransaction). Ich vermute, dass irgendwo zwischen dem Schreiben noch gelesen wird, zwischendurch aber dort wiederum vorher von woanders geschrieben wird. Ist ja eigentlich die einzig logische Erklärung. 😉 Aber ich finde eben die Stelle nicht...

With (NOLOCK) z.B. Die Doku ist hier.

Beik Express gibt es keine Priorisierung. Alle Prozesse sind gleichberechtigt.
Also functioniert dein Trick nicht (IsolationLevel), das gibt es nur in der Bezahlversion.

Deine Meldung sagt das ein Anderer SQL Prozess deiner Transaction den zugriff verweigert.
Das heist ein anderer SQL-Prozess arbeitet auf der Tabelle.
MSSQL macht standartmässig Pagelocking und nicht Rowlocking.

Vorgehensweise:
Wenn ein Deadlock auftritt must du dir mit den SQL-Tools alle Jobs anschauen.
Die Jobs die auf einen warten werden dort angezeigt.
So bekommst du dann die Info welches SQL das Problem verursacht.

Wenn ich/das Forum helfen soll must du erst mal die SQL posten. Dazu bitte die Tabellen Strucktur mit Index/PK.
Generell ist das weniger ein Problem für ein Forum.
Es gibt auch Profiler Software für SQL Server, die da mehr infos gibt.
Wieviele Transaktionen pro Minute habt ihr?

Viel erfolg beim Fehler finden.

MfG
Björn

Das Leben ist schön!

Interessant, das Statement kannte ich wirklich noch nicht, schau ich mir mal an.

Wie gesagt wir haben auch eine Developer-Edition zum Test im Einsatz, bei der das Problem auch auftritt und die müsste die Priorisierung ja unterstützen. Scheint also nicht am Isolation-Level zu liegen. Wenn du "Standard" schreibst, kann man das wohl auch umstellen auf Rowlocking?

Mit SQL-Tools meinst jetzt nicht das Management-Studio? Ich habe mir über die Systemtabellen bereits eine Abfrage gebastelt, die mir ausgibt, welcher SQL-Benutzer welches Statement >gerade< ausführt wird. Aber wenn der Transaktionsfehler kommt, ist das hängende Statement ja schon gekillt und im Prinzip alles zu spät. Und "dummerweise" tritt das Phänomen ja auch ca. 1-2x am Tag auf und ist auch nicht reproduzierbar - oder ich hab den Zusammenhang einfach noch nicht gefunden.

Hm, involviert in den vermuteten Ablauf, wo der Fehler auftritt, sind etwa 8 Prozeduren, welche wiederum 3 Views und einige Funktionen bedienen. Summa summarum denke ich sind etwa 10-12 Tabellen bei der ganzen Sache betroffen - ist eine relativ große Datenbank mit viel T-SQL und 2 Assembys drin. Entsprechend ists schwierig, alle SQL-Statements hier aufzulisten. 😉
Bei ca. 5-10 Leuten, die gleichzeitig mit dem Programm arbeiten, haben wir etwa 5-15 Transaktionen pro Minute schätze ich. Je nachdem wie oft die Leute eben auf speichern drücken. 😉 Vielleicht sollte ich mich mal mit solchen Profilern auseinander setzen. Ich bräuchte eigentlich nur ein Tool, welches sämtliche Statements der DB-Instanz mitloggt und den jeweiligen usern zuordnet.

Hey ,
das ist mal ein brauchbare Antwort 😃
Wenn ihr nur max 15 User habt und keine Jobs dann solltgest du keine Deadlock haben.
Deadlocks werden nicht so schnell aufgelöst wie du es hier schreibst. Im normalfall
dauern diese Minuten.
Ich bedauer das ich nicht mit 2008 arbeite.
Kann dir leider nichgt genau den passenden Tip geben.
Um den Fehler zu finden solltest du deine DB Architecktur unter die Lupe nehmen.

MfG
Bjön

Das Leben ist schön!

Ich bräuchte eigentlich nur ein Tool, welches sämtliche Statements der DB-Instanz mitloggt und den jeweiligen usern zuordnet.

Bei der Express Version fehlt vielleicht ein solches Tool, aber bei der Develop Edition ist es ziemlich sicher bereits bei der SQL Installation dabei, und nennt sich SQL Profiler. Das Tool sollte eigentlich bei allen Problemen an der DB die Anlaufstelle Nummer eins sein, wenn man nich auf andere kostspieligere Tools zurückgreifen will.

TIP: UPDATE [TABELLENNNAME] WITH (ROWLOCK) ....

Das kann schon viel helfen, wenn kein Pagelock mehr gemacht wird.
Und bei 15 Benutzer wirst du keine Performanc probleme wegen Rowlock bekommen.

Das Leben ist schön!

Hallo.

Tut mir leid, dass ich mich so lange nicht gemeldet habe, war im Urlaub und dann viel Arbeitsstress. ^^

Das Problem hat sich scheinbar von allein gelöst. Wir haben in der Zwischenzeit eine komplett neue Oberfläche eingeführt. Ich nehme an, dass sich bei der alten (über 6 Jahre historisch gewachsenen) Oberfläche einfach ein paar Threads gegenseitig abgeschossen haben, da damals sehr viel aufgrund von Zeitnot in die Oberfläche gelegt wurde. Jetzt haben wir ein komplett neu entwickeltes GUI und teils auch die Mittelschicht - und bisher kein einziges Mal mehr die Meldung. Hoffe das wars wirklich.

Danke für die vielen Hinweise, die werde ich trotzdem alle mal ausprobieren, man kann ja immermal was dazu lernen. 😃

Lars

Auch wenn sich Dein Problem inzwischen schon von alleine gelöst hat (ich liebe solche Probleme) hier noch Anmerkungen zu Transaktionen :

Auch die Reihenfolge, wie auf Daten zugegriffen wird, ist im Prinzip überall gleich.

Wenn die Reihenfolge, in der auf die Tabellen zugegriffen wird (lesen oder schreibend je nach Transaktionslevel) immer gleich ist können keine Deadlocks auftreten. Das kann man sogar beweisen, ich habe es nur in der Praxis ausprobiert.

Wenn in Deiner Applikation Deadlocks auftreten dann musst Du diese selbst behandeln : Nach dem Rollback musst Du die Transaktion erneut ausführen.

Wenn ihr nur max 15 User habt und keine Jobs dann solltgest du keine Deadlock haben.

Man kriegt einen Deadlock sogar mit 2 Usern hin, oder 1 User mit 2 Fenstern.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3