Ich denke, Sie versuchen, das Problem auf falsche Weise zu lösen. Was Sie wollen, ist ein Höchstmaß an Schutz der Datenbankkonsistenz. Wenn zwei Personen gleichzeitig eine gespeicherte Prozedur ausführen, kann die Datenbankkonsistenz verletzt werden.
Zum Schutz vor verschiedenen Arten von Datenbankinkonsistenzen verfügt der SQL-Standard über vier Transaktionsisolationsstufen:
- LESEN SIE UNCOMMITTED, wenn Transaktionen im Grunde ihren Wert verlieren und andere Transaktionen schmutzige Daten sehen. Benutze das nicht!
- READ COMMITTED, wenn bei Transaktionen nur festgeschriebene Daten angezeigt werden, es jedoch zu Inkonsistenzen kommen kann, bei denen zwei Transaktionen einander über die Zehen treten können
- REPEATABLE READ, bei dem eine Art von Inkonsistenz, nicht wiederholbares Lesen, gelöst wird
- SERIALIZABLE, das garantiert, dass es eine virtuelle Reihenfolge gibt, in der die Ausführung der Transaktionen zu den Ergebnissen führen würde, zu denen ihre Ausführung geführt hat
Der SQL-Standard verwendet jedoch einen auf Sperren basierenden Ansatz für diese Datenbankinkonsistenzen. Aus Leistungsgründen verwenden viele Datenbanken einen auf Snapshot-Isolation basierenden Ansatz, der im Wesentlichen folgende Ebenen aufweist:
- READ COMMITTED ist das gleiche wie beim Sperren von Datenbanken
- SNAPSHOT ISOLATION, bei der die Datenbank einen Snapshot aller Daten sieht und versucht, eine Zeile zu aktualisieren, die durch eine andere Transaktion aktualisiert wurde, wird sie abgebrochen, es können jedoch einige bekannte Anomalien auftreten
- SERIALIZABLE ist dasselbe wie in sperrbasierten Datenbanken, diesmal jedoch auf andere Weise implementiert, nicht durch Sperren, sondern durch Sicherstellen, dass keine Serialisierungsverletzungen vorliegen. Wenn eine solche Verletzung erkannt wird, wird eine Transaktion abgebrochen
Die Transaktionsstornierungen in diesen auf Snapshot-Isolation basierenden Datenbanken klingen möglicherweise besorgniserregend, aber andererseits bricht jede einzelne Datenbank eine Transaktion aufgrund eines Deadlocks ab, sodass jede vernünftige Anwendung ohnehin in der Lage sein muss, eine Transaktion erneut zu versuchen.
Was Sie wollen, ist die Isolationsstufe SERIALIZABLE : Sie stellt sicher, dass jede parallele Ausführung der Transaktionen auch zu einem guten Zustand führt, wenn unabhängig voneinander nacheinander ausgeführte Transaktionen zu einem guten Zustand führen. Glücklicherweise hat Michael Cahill in seiner Dissertation herausgefunden, wie die SERIALIZABLE- Isolationsstufe mit geringem Aufwand von Snapshot-isolierten Datenbanken unterstützt werden kann.
Wenn bei Verwendung einer SERIALIZABLE- Isolationsstufe in einer isolierten Snapshot-Datenbank zwei Personen gleichzeitig versuchen, die gespeicherte Prozedur auszuführen und sich gegenseitig auf die Zehen treten, wird eine der Transaktionen abgebrochen.
Unterstützt SQL Server nun wirklich die Isolationsstufe SERIALIZABLE (anstatt die Snapshot-Isolation hinter dem Schlüsselwort SERIALIZABLE zu maskieren )? Ehrlich gesagt weiß ich nicht: Die einzige mir bekannte Datenbank, die dies unterstützt, ist PostgreSQL.
Obwohl ich keine SQL Server-spezifischen Ratschläge gegeben habe, veröffentliche ich diese Antwort dennoch, da Benutzer von PostgreSQL und Benutzer anderer Datenbanken, die einen Wechsel zu PostgreSQL in Betracht ziehen können, von meiner Antwort profitieren können. Benutzer von Nicht-PostgreSQL-Datenbanken, die nicht zu PostgreSQL wechseln können, können ihren bevorzugten Datenbankanbieter unter Druck setzen, eine echte SERIALIZABLE- Isolationsstufe anzubieten .