Ist diese gespeicherte Prozedur, thread-safe? (oder wie auch immer die entspr ist auf SQL-Server)
Mit Hilfe anderer, ALSO habe ich geklopft, bis ein paar Tabellen und Gespeicherten Prozeduren an diesem morgen, da bin ich weit von einem DB-Programmierer.
Wäre jemand Verstand casting ein Auge auf und sagt mir, ob es thread-safe? Ich denke, das ist wohl nicht der Begriff DBAs/DB-Entwickler verwenden, aber ich hoffe, Sie bekommen die Idee: im Grunde, was passiert, wenn dieses sp ausführt, und ein anderer kommt zusammen zur gleichen Zeit? Könnte einen stören die anderen? Ist dies auch ein Problem in SQL/SPs?
CREATE PROCEDURE [dbo].[usp_NewTicketNumber]
@ticketNumber int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [TEST_Db42].[dbo].[TicketNumber]
([CreatedDateTime], [CreatedBy])
VALUES
(GETDATE(), SUSER_SNAME())
SELECT @ticketNumber = IDENT_CURRENT('[dbo].[TicketNumber]');
RETURN 0;
END
- Ich Stimme völlig mit gbn Antwort, möchte aber noch hinzufügen, dass können Sie einfach herausfinden, sich selbst - Sie können nur das ausführen der gespeicherten Prozedur, die gleichzeitig von zwei oder mehr verbindungen in einer Schleife mnay mal (>1mln), und sehen Sie selbst.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werden Sie wahrscheinlich nicht wollen, um mit IDENT_CURRENT - dies gibt die Letzte Identität, die auf dem Tisch in Frage, in einer Sitzung oder einem Gültigkeitsbereich. Wenn jemand anderes hat eine insert-zur falschen Zeit erhalten Sie Ihre id anstelle!
Wenn Sie wollen, um die Identität erzeugt, die durch das einfügen, dass Sie nur durchgeführt, dann ist es am besten, um die AUSGABE - Klausel, um es abzurufen. Früher war es üblich, dass die SCOPE_IDENTITY() für diese, aber es gibt Probleme mit, dass Sie unter parallele Ausführung von Plänen.
Den wichtigsten SQL-entspricht der thread-Sicherheit ist, wenn mehrere Anweisungen ausgeführt werden, dass es zu unerwarteten oder unerwünschten Verhalten. Die beiden wichtigsten Arten von Verhalten, die ich denken kann, sind sperren (insbesondere deadlocks) und Parallelität Probleme.
Locking-Probleme, die auftreten, wenn eine Anweisung hält andere Aussagen aus dem Zugriff auf die Zeilen mit dem es arbeitet. Dies kann die Leistung beeinträchtigen und im schlimmsten Fall zwei Aussagen, die änderungen vornehmen, die nicht in Einklang gebracht werden und ein deadlock Auftritt, verursacht eine Anweisung beendet werden.
Jedoch eine einfache einfügen wie die, die Sie haben, sollte nicht dazu führen, sperrt, es sei denn, etwas anderes beteiligt ist (wie Datenbanktransaktionen).
Concurrency-Probleme (Beschreibung sehr schlecht) werden verursacht durch eine Reihe von änderungen an der Datenbank-Datensätzen überschreiben andere änderungen an denselben Datensätzen. Auch das sollte kein problem sein, wenn das einfügen eines Datensatzes.
OUTPUT
. Ich werde zurückziehen, mein downvote und bieten ein upvote 🙂Den sichersten Weg zu gehen, hier wäre wahrscheinlich die Verwendung der Output-Klausel, da gibt es einen bekannten bug in scope_idendity unter bestimmten Umständen ( multi-parallel-processing ).
Diese Weise sollten Sie thread-sicher, da die output-Klausel verwendet die Daten, dass der Einsatz tatsächlich fügt, und Sie werden keine Probleme haben, über Bereiche oder Sitzungen.
Würde ich nicht verwenden GEGENZUG für die sinnvolle Verwendung von Daten: entweder recordset-oder output-parameter. ZURÜCKKEHREN würden, die normalerweise verwendet werden, für die Fehler-Zustände (wie system stored procs in den meisten Fällen):
Sie können auch die OUTPUT-Klausel zur Rückgabe einer Datensatzgruppe statt.
Dies ist "thread-safe", d.h. es können gleichzeitig ausgeführt werden.
First off, warum nimmst du nicht einfach die Rückkehr der neuen ticket-Nummer statt der 0 die ganze Zeit? Irgendein besonderer Grund dafür?
Zweitens, um absolut sicher zu sein, sollten Sie wickeln Sie Ihre INSERT-und SELECT-Anweisung in einer TRANSAKTION, so dass nichts von außen eingreifen kann.
Drittens, mit SQL Server 2005 und höher, würd ich wickle meine Anweisungen in einen TRY....CATCH-block und für die Transaktion ein Rollback, wenn es fehlschlägt.
Als Nächstes würde ich versuchen zu vermeiden, die Angabe der Datenbank-server (TestDB42) in meinem Verfahren Wann immer möglich - was ist, wenn Sie bereitstellen möchten, der proc auf einen neuen server (TestDB43) ??
Und zu guter Letzt, würde ich nie ein SET NOCOUNT in einer gespeicherten Prozedur - es kann dazu führen, die der Anrufer irrtümlicherweise denken, die gespeicherte Prozedur fehlgeschlagen ist (siehe mein Kommentar zu gbn unten - dies ist ein potenzielles problem, wenn Sie mit ADO.NET SqlDataAdapter-Objekte; siehe die MSDN docs auf, wie dies zu ändern ADO.NET Daten mit SqlDataAdapter für weitere Erläuterungen).
Also mein Vorschlag für deine gespeicherte Prozedur wäre:
Marc
Ich Stimme mit David Hall ' s Antwort, ich möchte nur erweitern ein wenig, warum ident_current ist absolut die falsche Sache zu verwenden, in dieser situation.
Hatten wir einen Entwickler hier, der es benutzte. Der Einsatz von der client-Anwendung geschah in der gleichen Zeit wurde die Datenbank importieren von Millionen von Datensätzen über einen automatisierten import. Die id zurückgegeben, um ihn von einem der Datensätze mein Prozess importiert. Er verwendet diese id, um das erstellen von Datensätzen für einige untergeordnete Tabellen, die waren jetzt an der falschen Datensatz. Schlimmer noch wir haben jetzt keine Ahnung, wie oft dies geschah, bevor jemand konnte Sie nicht finden die Informationen, die sollten schon in den child-Tabellen (seine änderungen wurden auf prod für mehrere Monate). Nicht nur meine automatisierten import haben, mischte sich mit seinem code, aber einem anderen Benutzer einfügen eines Datensatzes an der gleichen Zeit hätte das gleiche getan. Ident_current sollte nie verwendet werden, um wieder die Identität von einem Datensatz nur eingefügt, wie es beschränkt sich nicht auf den Prozess, der ihn aufruft.