Sie beschreiben im Grunde einen klassischen warteschlangenbasierten Workflow, und Sie sollten die Verwendung eines echten in Betracht ziehen Warteschlange .
Zum Zwecke der Diskussion, hier ist, wie Sie erreichen, was Sie wollen:
- bestimmte Ressource beanspruchen:
SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK) WHERE key = @key
. Wird blockiert, wenn die Ressource bereits beansprucht wird. Verwenden Sie Sperrzeitüberschreitungen, um eine Ausnahme zurückzugeben, wenn die Ressource bereits beansprucht wurde.key
muss indexiert und einzigartig sein. - nächste verfügbare Ressource:
SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK, READPAST) ORDER BY <accessorder>
. Sie müssen eine Reihenfolge definieren, um die Präferenz der Ressourcen auszudrücken (älteste, höchste Priorität usw.) - eine beanspruchte Ressource freigeben:
COMMIT
Ihre Transaktion.
Der Kern des Problems besteht darin, die richtigen Sperrhinweise zu verwenden, und diese Art von Problem erfordert explizite Sperrhinweise, um sie zu lösen. UPDLOCK fungiert als „Anspruchs“-Sperre. ROWLOCK erzeugt die richtige Granularität, die verhindert, dass der Server auf eine Seitensperre „optimiert“. Mit READPAST können Sie beanspruchte Ressourcen überspringen. Das Platzieren von UPDLOCK auf den Zeilen sperrt die Zeile und ermöglicht Ihnen, sie später zu aktualisieren, verhindert jedoch andere Operationen wie gewöhnliche read-committed SELECTs, die die gesperrte Zeile blockieren. Die Idee ist jedoch, dass Sie die Zeile trotzdem aktualisieren, wodurch eine unvermeidliche X-Sperre platziert wird. Wenn Sie die Tabelle verfügbarer halten möchten, können Sie App-Sperren stattdessen, aber es ist wesentlich schwieriger, es richtig abzuziehen. Sie müssen eine App-Sperre für einen Zeichenfolgedeskriptor der Ressource anfordern, z. B. den Schlüsselwert oder eine CHECKSUM
des Schlüssels oder es ist %%LOCKRES%%
Wert. Mit App-Sperren können Sie den Umfang des „Anspruchs“ von einer Transaktion trennen, indem Sie die App-Sperre im Bereich „Sitzung“ anfordern, aber dann müssen Sie den Anspruch manuell freigeben (App-Sperren im Bereich „Transaktion“ werden zum Commit-Zeitpunkt freigegeben). . Aber Vorsicht, es gibt tausend Möglichkeiten, sich mit App-Sperren selbst ins Knie zu schießen.