Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Threadsafe UPDATE TOP 1 für FIFO-Warteschlange

Mein Anliegen wäre doppelte [Rechnungs-ID]
Mehrere Druckanfragen für dieselbe [Rechnungs-ID]

Bei der ersten Aktualisierung wird EINE Zeile set [Status] = 'Printing'

Bei der zweiten Aktualisierung erhalten alle [InvoiceID]-Zeilen set [Status] = 'Printed'
Dies würde sogar Zeilen mit Status ='Entwurf'

setzen

Vielleicht ist es das, was Sie wollen

Ein anderer Prozess könnte dieselbe [Rechnungs-ID] vor dem set [Status] = 'Print' abrufen

Einige Duplikate werden also gedruckt und andere nicht

Ich gehe mit Kommentaren zur Verwendung der update lock

Dies ist nicht deterministisch, aber Sie könnten einfach top (1) nehmen und überspringen Sie die order by . Sie werden in der Regel die neueste Zeile erhalten, dies ist jedoch nicht garantiert. Wenn Sie die Warteschlange löschen, erhalten Sie sie alle.

Dies zeigt, dass Sie 'draft' =1

verlieren können
declare @invID int; 
declare @T table (iden int identity primary key, invID int, status tinyint);
insert into @T values (1, 2), (5, 1), (3, 1), (4, 1), (4, 2), (2, 1), (1, 1), (5, 2), (5, 2);
declare @iden int;
select * from @t order by iden;

declare @rowcount int = 1; 
while (@ROWCOUNT > 0)
    begin
        update top (1) t 
        set t.status = 3, @invID = t.invID,  @iden = t.iden
        from @t t 
        where t.status = '2';
        set @rowcount = @@ROWCOUNT;
        if(@rowcount > 0)
            begin 
                select @invID, @iden;
                -- do stuff  
                update t 
                set t.status = 4
                from @t t
                where t.invID = @invID; -- t.iden = @iden;
                select * from @T order by iden;
            end
    end