2016-06-09 13 views
1

Ich nahm das NuGet-Paket für DistributedLock für meine. NET-Anwendung, die auf mehreren Servern ausgeführt wird. Für diejenigen, die es nicht wissen, verwendet es SQL Server's application lock functionality, um eine einfache Möglichkeit der Sperrung über verschiedene Maschinen bereitzustellen. Für das, was ich benutzt habe, war es in Ordnung. Ich habe mich jedoch gefragt, ob die Reihenfolge, in der die Sperren überprüft wurden, dazu führt, dass der Auftrag bei der Freigabe der Sperre beibehalten wird.DistributedLock Erwerben Auftrag

Zum Beispiel ... sagen wir, meine Anwendung liest aus einer Warteschlange und verarbeitet dann jede Nachricht der Reihe nach. Was wäre, wenn jede Nachricht von Haushalten handeln würde und ich jede Nachricht für einen Haushalt in Reihenfolge verarbeiten wollte? Die erste gefundene Nachricht könnte das Acquire von DistributedLock verwenden, um zu überprüfen, ob das Konto frei ist, es zu sperren, wenn es frei ist, und mit der Verarbeitung der Nachricht zu beginnen. Angenommen, die Warteschlangenlistener-App läuft auf einem anderen Server und liest eine andere Nachricht aus der Warteschlange für denselben Haushalt. In diesem Fall würde Acquire warten, bis die Sperre für den Haushalt frei war, und dann erneut sperren und die Nachricht verarbeiten.

Aber was, wenn es eine dritte Maschine gab, auf der die gleiche App lief und eine Nachricht mit derselben Haushaltskennung auftrat?

So Maschine # 1 packt die erste Nachricht für Haushalt ID A01, sperrt es und beginnt, es zu verarbeiten. Maschine # 2 ergreift eine zweite Nachricht in der Warteschlange für A01 und wartet. Maschine # 3 ergreift eine dritte Nachricht aus der Warteschlange für A01 und wartet.

In dem Fall oben, wenn Maschine # 1 fertig ist Verarbeitung seiner Nachricht für A01 und gibt die Sperre wird Maschine # 2, die die zweite Nachricht für A01 abgeholt, nächste vor Maschine # 3? Oder wird es praktisch zufällig sein und beide Maschinen # 2 oder # 3 könnten die nächste Sperre erhalten? Wird die Bestellung beibehalten?

+0

Wenn jede Nachricht ihre eigene Sperre hat, warum sollte es irgendwelche Bestellanforderungen geben? Warum würde ein Acquirer in Ihrem Beispiel blockieren? – usr

Antwort

1

Ich präsentiere diese Antwort mit der Einschränkung, dass ich ein DBA bin und kein Anwendungsentwickler (ich weiß gerade genug C#, um gefährlich zu sein).

Mit Blick auf die beiden Dinge, die Sie verknüpft haben, würde ich nicht davon ausgehen, dass es eine Bestellung auf die Anfrage gibt. sp_getapplock verwendet dieselbe Sperrfunktionalität, die SQL zum Sperren von Elementen wie Zeilen und Tabellen verwendet. Sie definieren nur den Namen einer virtuellen Ressource. Als solches, wenn eine Aufgabe für ein Schloss durch sp_getapplock fragt, geschieht folgendes (auf hohem Niveau)

  • Die Aufgabe geht in die runnable Warteschlange
  • Die Aufgabe an die Spitze der Warteschlange erhält
  • wenn die Sperre derzeit nicht von einem anderen Prozess gehört, können Sie es bekommen und du bist
  • getan, wenn die Sperre wird derzeit von einem anderen Prozess gehört, gehen Sie in den Wartezustand
  • wenn die Sperre aufgehoben wird, Ihre Prozess wird signalisiert, "aufzuwachen", an welchem ​​Punkt t es geht in die ausführbare Warteschlange (d. h. zurück zu dem ersten Schritt)

Die gotcha ist, dass jeder seine eigenen Scheduler runnable Warteschlange haben (das heißt es nicht nur eine Warteschlange pro runnable SQL-Instanz), so welcher Prozess zuerst bekommt ist nicht deterministisch.

Wenn Sie in der Auftragsabwicklung suchen, können Sie sich Service Broker oder eine andere Art von Warteschlangentechnologie mit Themen und Lieferung in der richtigen Reihenfolge ansehen.

+0

Ich stimme dir zu ... Ich vermutete so viel, dachte aber, ich würde fragen. Vielen Dank – Eves