2012-04-11 2 views
1

ich eine sproc bin beibehalten, wo der Entwickler seinen eigenen Verriegelungsmechanismus mir umgesetzt hat, aber es fehlerhaft schien:Lassen Sie jeden Lauf eines sproc Prozess seinen Anteil an Zeilen

CREATE PROCEDURE Sproc 1 
AS 

Update X 
set flag = lockedforprocessing 
where flag = unprocessed 

-- Some processing occurs here with enough time to 
-- 1. table X gets inserted new rows with a flag of unprocessed 
-- 2. start another instance of this Sproc 1 that executes the above update 

Select from X 
where flag = lockedforprocessing 

-- Now the above statement reads rows that it hadn't put a lock on to start with. 

Ich weiß, dass ich es einfach einwickeln sproc innerhalb einer Transaktion mit Isolationsstufe von SERIALIZABLE, aber das möchte ich vermeiden.

Das Ziel ist

  1. , die mehrere Instanzen dieser sproc zugleich laufen können und ihren eigenen „Share“ der Datensätze verarbeiten, um maximalen Concurrency zu erreichen.
  2. Eine Ausführung des sproc nicht auf einem vorherigen Lauf warten sollte, die noch

ich, da es die neuen Datensätze mit einem Wert von „nicht verarbeiteten verhindern nicht glaube nicht, dass WIEDERHOLBARE READ ausgeführt wird kann hier helfen "gelesen werden (korrigieren Sie mich, wenn ich bitte falsch liege).

Ich entdeckte gerade die sp_getlock sproc und es würde den Fehler beheben, aber exaction serialisieren, was nicht mein Ziel ist. Eine Lösung, die ich sehe, besteht darin, dass jede Ausführung des Procs eine eigene eindeutige GUID erzeugt und diese der Markierung zuweist, aber irgendwie denke ich, dass ich etwas simuliere, das SQL Server bereits aus der Box lösen kann.

Ist die einzige Möglichkeit, dass jeder Lauf eines Sproc-Prozesses "teilen" der Zeilen, um es in SERIALIZABLE haben?

Grüße, Tom

+0

Einer der Antwort auf [eine Tabelle als eine Warteschlange verwenden] (http : //stackoverflow.com/questions/4686726/sql-server-using-a-table-as-a-queue) kann Ihnen helfen. – AakashM

Antwort

0

Angenommen, es in X ein ID-Feld ist, kann eine temporäre Tabelle aktualisierter Xs helfen:

CREATE PROCEDURE Sproc 1 
AS 
-- Temporary table listing all accessed Xs 
    declare @flagged table (ID int primary key) 
-- Lock and retrieve locked records 
    Update X 
     set flag = lockedforprocessing 
    output Inserted.ID into @flagged 
    where flag = unprocessed 

-- Processing 
    Select from X inner join @flagged f on x.ID = f.ID 

-- Clean-up 
    update X 
     set flag = processed 
    from x inner join @flagged f on x.ID = f.ID 
+0

Sehr elegante Lösung. Ich hoffe, dass unser prod sql server die Ausgabe unterstützt, wie sie in einigen der späteren sql Server Versionen eingeführt wurde. AFAIK – buckley

+0

@buckley Es wurde 2005 eingeführt. –

Verwandte Themen