Ist es möglich, einen Deadlock mit schreibgeschütztem Zugriff zu erstellen?

Ich habe eine VB6-Anwendung Zugriff auf eine einzelne Tabelle auf einem MSSQL2000 server über ADO. Ich verwende schreibgeschützten Zugriff (adOpenStatic, adLockReadOnly) Es gibt noch andere Anwendungen im Netzwerk, die Änderungen an der Tabelle vornehmen.

Aus irgendeinem Grund bekomme ich Fehler, wie meine Bewerbung als Deadlock-Opfer gewählt wird.

Ich bin wirklich verwirrt: Warum kann es einen Deadlock geben, wenn ich nur aus einem einzigen Tisch lese ? Ich würde erwarten, Timeouts, wegen der Schrift der anderen Anwendungen, aber nicht ein Deadlock …

Kann jemand etwas beleuchten?

UPDATE: 2009-06-15 Ich interessiere mich immer noch für eine Lösung für dieses Problem. Also stelle ich noch weitere Informationen zur Verfügung:

  • Es macht keinen Unterschied, ob ich adOpenForwardOnly oder adOpenStatic wähle
  • Es macht keinen Unterschied, ob die Cursorposition Client oder server ist.

Es ist möglich, dass eine einzelne SELECT-statement aufgrund eines Vorhandenseins eines nicht gruppierten Indexes gegen eine einzelne UPDATE- oder DELETE-statement sperrt, betrachte das folgende Szenario:

Der Leser (Ihre App) erhält zuerst eine gemeinsame Sperre für den nicht gruppierten Index, um eine search durchzuführen, und versucht dann, eine gemeinsame Sperre auf der Seite zu erhalten, die mit den data übereinstimmt, um die data selbst zurückzugeben.

Der Schreiber (andere App) erhält zunächst eine exklusive Sperre auf der databaseseite, die die data enthält, und versucht dann, eine exklusive Sperre für den Index zu erhalten, um den Index zu aktualisieren.

Weitere Informationen zu diesem (und anderen) Typ von Deadlock finden Sie im Microsoft KB-Artikel Q169960 ( http://support.microsoft.com/kb/q169960/ )

Auch können Sie einen Blick auf Google auf, wie man Deadlock-Trace-Informationen (Trace-Flag 1222) zu erhalten – dies wird berichten, genau, welche SQL-statementen sind in Konflikt über welche objecte, wenn ein Deadlock auftritt. Dies ist ein ziemlich anständig aussehender Artikel – http://blogs.msdn.com/bartd/archive/2006/09/09/747119.aspx

Ich denke, es gibt eine Reihe von Möglichkeiten in den Antworten, die hier bereits vorhanden sind. Da du nur geteilte Sperren nimmst, kann der Deadlock nicht auf die Eskalation verzichten und muss einfach Schlösser erwerben, die mit denen, die in einem anderen process erworben wurden, nicht kompatibel sind und diese Sperren in einer anderen Reihenfolge erwerben …

Ihre gemeinsamen Sperren sind nicht kompatibel mit einem anderen process, der exklusive Schlösser nimmt. Das Szenario könnte so etwas ausführen …

  1. Sie nehmen die gemeinsame Sperre auf Ressource A
  2. Anderer process nimmt exklusive Sperre auf Ressource B
  3. Andere process versucht, exklusive Sperre auf Ressource A zu nehmen, und Blöcke warten auf Sie, um Ihre gemeinsame Sperre auf A.
  4. Sie versuchen, eine gemeinsame Sperre für die Ressource B zu machen, und würde das Warten auf den anderen process beenden, um seine exklusive Sperre auf B freizugeben, außer dass Sie jetzt in einer Deadlock-Situation sind, die vom server identifiziert wird und es einen process zum Töten wählt .

NB Deadlocks können mehr Spieler als nur 2. Manchmal gibt es eine ganze Kette von verwobenen Aktivitäten, die in einem Deadlock führt, aber das Prinzip ist das gleiche.

Oft, wenn mehrere Anwendungen auf die gleiche database zugreifen, gibt es einen DBA, der alle Zugriff über gespeicherte Prozeduren verwaltet, so dass er sicherstellen kann, dass Ressourcen immer in der gleichen Reihenfolge gesperrt sind. Wenn Sie nicht in dieser Situation sind und die anderen Anwendungen Ad-hoc-SQL-statementen verwenden, müssen Sie ihren Code überprüfen, um herauszufinden, ob sie mit Ihrer App in der Art, wie ich beschrieben habe, in Konflikt stehen könnten. Das klingt nicht lustig

Eine pragmatische Lösung könnte sein, um den Fehler zu fangen, wenn Ihre Transaktion als Deadlock-Opfer getötet wird, und einfach wiederholen Sie die Transaktion mehrmals. Je nachdem, wie viel Aktivität die anderen Apps generieren, können Sie auf diese Weise akzeptable Ergebnisse erzielen.

Liest kann immer noch Schlösser entstehen, damit der DB sicherstellen kann, dass ein Schreibvorgang nicht in der Mitte eines nicht-atmischen Lesens erfolgt. Mit anderen Worten, das Leseschloss sorgt dafür, dass Sie einen genauen, gleichmäßigen Schnappschuss von allen data erhalten, die Sie sitzen.

adOpenForwardOnly du das gleiche Verhalten mit adOpenForwardOnly ?

Vielleicht möchten Sie überprüfen, ob Ihre SQL server-Statistiken aktuell sind. Oder du könntest deine DBA dazu bringen, alle Indizes neu zu erstellen. Viele Verriegelungsprobleme sind auf veraltete Statistiken / Indizes zurückzuführen.

Wäre es nicht so?

Andere Anwendung : Schreiben in Tabelle (Erwerb Schreibschloss auf Tabelle)

Ihre Bewerbung : Lesen Sie aus der Tabelle (erwerben Sie die Sperre auf dem Tisch, können Sie nicht auf die Sperre schreiben).

Es hängt sowohl vom Verhalten der Anwendung ab. Ihre App kann sicher auf die andere warten, um Ressourcen freizugeben.

Ein Deadlock bezieht sich auf eine Bedingung, wenn zwei oder mehr processe aufeinander warten, um eine Ressource freizugeben, oder mehr als zwei processe warten auf Ressourcen in einer kreisförmigen Kette. Sicher können Sie einen Deadlock mit schreibgeschütztem Zugriff erstellen, weil das Lesen NICHT warten wird.

Es gibt eine schöne Erklärung über die Deadlock-Bedingungen an der Wikipedia