Wir haben eine Handvoll Zeilen in unserer Datenbank gefunden, die gegen eine aktive Einschränkung verstoßen. Wie ist das möglich?
Die Einschränkung ist aktiv, da wir nicht einfach manuell eine Zeile hinzufügen können, die diese Einschränkung umgeht. Wenn wir jedoch laufen CHECKCONSTRAINTS(Files)
, stellen wir fest, dass es während unserer Testläufe gelegentlich umgangen wurde. Die fraglichen Reihen wurden alle innerhalb einer halben Sekunde voneinander erstellt, was auf eine Art Rennbedingung hindeutet.
Hier ist die Einschränkung, die auf die Tabelle angewendet wird. Die Regel soll die Eindeutigkeit des Namens in einem bestimmten übergeordneten Ordner sicherstellen:
ALTER TABLE Files ADD CONSTRAINT UniqueNameInParentFolder CHECK
CheckUniqueNameInFolder(ParentFoldersID, Name) = 1;
Diese Einschränkung ruft eine Funktion auf, die folgendermaßen aussieht:
-- first check for the new name in the Folders table
IF ((SELECT COUNT(*) FROM Folders
WHERE ParentFoldersID = @FoldersID AND Name = @Name) = 0)
BEGIN
-- then check for it in the Files table
IF ((SELECT COUNT(*) FROM Files
WHERE ParentFoldersID = @FoldersID AND Name = @Name) <= 1)
RETURN 1
END
RETURN 0
Einzelne Zeilen werden innerhalb von Transaktionen hinzugefügt, daher fällt es mir schwer zu verstehen, wie sich doppelte Zeilen über diese Einschränkung hinausschleichen.
Folders
es dort auch eine ähnliche Anzahl von Verstößen gibt. Wir verwenden derzeitREAD_COMMITTED_SNAPSHOT
.