Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

AGGIORNAMENTO SQL Threadsafe TOP 1 per la coda FIFO

La mia preoccupazione sarebbe la duplicazione di [InvoiceID]
Richieste di stampa multiple per lo stesso [InvoiceID]

Al primo aggiornamento UNA riga ottiene set [Status] = 'Printing'

Al secondo aggiornamento tutte le righe [InvoiceID] ottengono set [Status] = 'Printed'
Ciò imposterebbe anche le righe con status ='bozza'

Forse è quello che vuoi

Un altro processo potrebbe prelevare lo stesso [ID fattura] prima che set [Status] = 'Print'

Quindi alcuni duplicati verranno stampati e altri no

Vado con i commenti sull'uso del update lock

Questo non è deterministico ma potresti semplicemente prendere top (1) e salta order by . Tenderai a ottenere la riga più recente ma non è garantita. Se svuoti la coda, li ottieni tutti.

Questo dimostra che puoi perdere 'bozza' =1

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