SQL Server 2008 gespeicherter Proc, der gleichzeitig zu Verzögerungen ausgeführt wird
Frage
Ich habe ein Problem, bei dem es anscheinend anscheinend das gleiche gespeicherte Verfahren aus zwei verschiedenen Fällen derselben Anwendung ausführt, und fragte mich, ob ich etwas tun könnte, um es zu lösen?
Ich glaube, das Problem liegt in der Art und Weise, wie SQL Server 2008 sich selbst behandelt, Zeilen sperrt und die SPS ausführt ... Dinge, von denen ich nicht wirklich viel weiß. Die App verwendet ADODB.Command
um die sp.
Ich habe einen VB6 exe (App.exe
), mehrmals auf dem einen Server. Diese App ruft in der Datenbank einen gespeicherten Proc auf, der die nächste Sequenznummer für diese App zurückgibt. Dieses Feld der Sequenznummer ist für die Instanz der Anwendung eindeutig - in einer Tabelle befindet sich 1 Zeile (tbl_SequenceNos
) Für jede Instanz der laufenden Anwendung.
Sagen wir zum Beispiel, wir haben Laufen: App[a].exe
und App[b].exe
tblSequenceNos
sieht aus wie:
iAppNo| iNextSequenceNo
a | 1234
b | 4567
Das gespeicherte Verfahren, um die nächste Sequenznummer zu erhalten, ist relativ einfach:
CREATE PROEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS
BEGIN
DECLARE @TempSequenceNo int
SELECT @NextSequenceNo = iNextSequenceNo
FROM tblSequenceNos
WHERE iAppNo = @AppNo
@NextSequenceNo = @NextSequenceNo + 1
UPDATE tblSequenceNos
SET iNextSequenceNo = @NextSequenceNo
WHERE iAppNo = @AppNo
END
Wenn beide App[a].exe
und App[b].exe
Versuchen Sie, dieses Verfahren auszuführen, um ihre zu erhalten NextSequenceNo
Wert, sie hängen ungefähr 30 Sekunden lang (ADO -Zeitüberschreitung?).
Da jede App nie die Reihe der anderen betrachtet, dachte ich, dass dies gleichzeitig funktionieren würde, ohne eine spezielle Sperre zu spezifizieren. Fehlt mir etwas? Ich dachte, ich muss vielleicht nur angeben, um die Zeile nur zu sperren, nicht die gesamte Tabelle oder Seite? - Ich weiß nicht, was SQL2008 standardmäßig tut.
Jede Hilfe wird sehr geschätzt! Vielen Dank im Voraus Andrew
Lösung
Ihre Prozedur ist nicht mit Thread sicher und erzeugt falsche Ergebnisse, da zwischen dem SELECT- und dem Aktualisieren mehrere Threads dieselbe Sequenz NR erhalten.
CREATE PROCEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS
DECLARE @var table(seq int);
UPDATE tblSequenceNos
SET iNextSequenceNo = @NextSequenceNo + 1
OUTPUT inserted.iNextSequenceNo INTO @var;
WHERE iAppNo = @AppNo
select @NextSequenceNo = seq from @var
GO
Stellen Sie außerdem sicher, dass Ihre IAPPNO -Spalte indiziert ist. (Dies bedeutet nur einen Index in dieser Spalte oder einen Index, in dem dieses Feld das erste Feld in Ihrem Index ist.)