SQL Server einfügen Abfrage für ein Forum
-
08-10-2019 - |
Frage
Unter Berücksichtigung eines Forum-Tabelle und viele Benutzer gleichzeitig Nachrichten in sie eingeführt wird, wie sicher ist diese Transaktion?
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @LastMessageId SMALLINT
SELECT @LastMessageId = MAX(MessageId)
FROM Discussions
WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId
INSERT INTO Discussions
(ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
VALUES
(@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)
IF @@ERROR = 0
BEGIN
COMMIT TRANSACTION
RETURN 0
END
ROLLBACK TRANSACTION
RETURN 1
Hier las ich letztes Meldungs ??und es erhöhen. Ich kann nicht Identity-Feld verwenden, da es in einer Gruppe eingefügt für jede Nachricht erhöht werden muss (nicht jede Meldung in Tabelle einfügen.)
Lösung
sollte Ihre Transaktion ziemlich sicher sein, in der Tat - schauen Sie sich die MSDN-Dokumentation auf der SERIALIZABLE Transaktionsebene :
SERIALIZABLE
Gibt die folgenden:
Statements kann keine Daten lesen, die geändert wurde, aber noch nicht begangen durch andere Transaktionen.
keine weiteren Transaktionsdaten ändern können, , die durch das gelesen wurde aktuelle Transaktion, bis die aktuellen Transaktion abgeschlossen ist.
Andere Transaktionen können nicht neue Zeilen mit Schlüsselwerten einzufügen, die würde fallen in den Bereich der Schlüssel gelesen von Erklärungen, die in der aktuellen Transaktion, bis die aktuelle Transaktion abgeschlossen ist.
Bereichssperren werden im Bereich von Schlüsselwerten gesetzt, die das Spiel Suchbedingungen der einzelnen Aussagen in einer Transaktion ausgeführt. Dies blockiert andere Transaktionen Aktualisierung oder alle Zeilen eingefügt, die in Frage kämen für eine der ausgeführten Anweisungen durch die aktuelle Transaktion. Das heisst dass, wenn eine der Aussagen in a Transaktion ausgeführt, um eine zweite Zeit, werden sie den gleichen Satz von lesen Reihen. Die Bereichssperren werden gehalten, bis die Transaktion abgeschlossen ist. Dies ist das restriktivsten der Isolations Ebenen, weil sperrt es ganze Bereiche der Schlüssel und hält die Sperren bis zum Transaktion abgeschlossen ist. weil Concurrency niedriger ist, verwenden Sie diese Option nur bei Bedarf. Diese Option hat die gleiche Wirkung wie Einstellung HOLDLOCK auf alle Tabellen in allen SELECT-Anweisungen in eine Transaktion.
Das Hauptproblem bei dieser Transaktion Isolationsstufe ist, dass es auf dem Server eine ziemlich schwere Last ist, und serialisiert keinen Zugang (wie der Name schon sagt), so dass Ihre Serverleistung und Skalierbarkeit werden leiden, z.B. mit einer sehr hohen Anzahl von Benutzern, werden Sie möglicherweise viele Timeouts für Benutzer wartet auf eine Transaktion bis zum Ende erhalten.
So mit dem leichteren Ansatz einer globalen Nachrichten-ID als INT IDENTITY
auf jeden Fall viel besser ist!