Ho bisogno di un suggerimento di aggiornamento in questo SP? Leggendo una riga di coda di dati più di una volta

StackOverflow https://stackoverflow.com/questions/8922797

Domanda

Il mio schema DB è lavoro -> (molti) JobData -> (molti) risultati. Un lavoro viene suddiviso in più righe di lavoro in modo che più thread possano elaborare "blocchi" del lavoro (ogni riga di JobData). Quindi i thread di elaborazione inseriscono le righe dei risultati per ciascuna delle righe di JobData elabora.

Un singolo thread tenta di leggere i risultati in un ciclo fino a quando tutti i risultati non vengono letti. Si noti che contemporaneamente i thread possono essere ancora elaborando le righe di JobData (fino a quando tutti vengono elaborati) e inserendo i risultati. Quindi, nel ciclo, ogni chiamata a questo SP passa in un jobKey ... eppure in qualche modo con questo codice, i risultati vengono letti più volte (frequenza molto bassa ... cioè <3 righe per 8000 righe di risultati) ma solo riproducibili casualmente.

Ho aggiunto un commento di seguito nel codice accanto alla mia istruzione superiore di aggiornamento su Updat. Grazie in anticipo.

BEGIN TRANSACTION

-- Create a temp table TO store the select results
DECLARE @UnReadResults TABLE
(
    ResultKey uniqueidentifier
)

-- Wouldn't expect a UPDLOCK is needed since UPDATE statements create exclusive lock anyway?  Do I need to SELECT WITH UPDLOCK first, then do the UPDATE statement?

UPDATE TOP ( @pageSize ) Result
SET rResultRead = 1
OUTPUT INSERTED.rKey INTO @UnReadResults
FROM Result r INNER JOIN JobData AS jd ON jd.jdKey = r.rJobDataKey
WHERE jd.jdJobKey = @jobKey AND rResultRead = 0

-- Just return Job (always the same), JobData (could vary if chunk of result rows
-- spans multiple JobDatas) and Results that I successfully 'grabbed' by joining
-- to my temp table

SELECT j.jKey, j.jStatus, j.jResultsRead, 
   jd.jdKey, jd.jdJobKey, jd.jdDateStart, jd.jdDateComplete, jd.jdStatus,
   r.rKey, r.rProfileKey, r.rProfileAuthID, r.rResult, r.rReadLock, r.rReadAttempts
FROM Job j
    INNER JOIN JobData jd
        ON jKey = jdJobKey
    INNER JOIN Result r
        ON jdKey = rJobDataKey
    INNER JOIN @UnReadResults urr
        on rKey = urr.ResultKey

COMMIT TRANSACTION

EDIT: volevo solo mettere ciò che ho messo in atto ora in base alla risposta @GBN. Escludendo l'intero SP, ma l'istruzione di aggiornamento è ora formattata come:

UPDATE TOP ( @pageSize ) Result
SET rResultRead = 1, rReadLock = @lock, rReadAttempts = rReadAttempts + 1
OUTPUT INSERTED.rKey INTO @UnReadResults
FROM Result r WITH ( ROWLOCK, READPAST, UPDLOCK ) INNER JOIN JobData AS jd ON jd.jdKey = r.rJobDataKey
WHERE jd.jdJobKey = @jobKey AND rResultRead = 0

Sono corso con successo ora per alcuni giorni, quindi spero di aver inchiodato il problema. Se questo non sembra un uso corretto dei suggerimenti per tavolo, sentiti libero di farmelo sapere.

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top