Suppongo che tu stia eseguendo su SQL Server (a causa del tag), in caso contrario la mia risposta non è applicabile. Il blocco da solo non è sufficiente. Se si utilizza il blocco del record del database, il server SqL bloccherà altri processi che tentano di accedere alla riga bloccata e, in effetti, gestirà solo una riga alla volta. La soluzione per voi è combinare il blocco delle righe con l'hint READPAST in modo che le righe bloccate da qualcun altro vengano saltate. Ecco ciò che ogni processo deve fare:
- selezionare riga successiva sbloccato per l'elaborazione e bloccarlo
- fare il lavoro
- aggiornamento della transazione fila e alla fine
select top 1 id, ... from TheTable with (updlock, readpast) where flag = 0
//do the work now
update TheTable set flag = 1 where id=<previously retrieved id>
La cosa bella è che l'operazione di selezionare la successiva riga sbloccata e bloccarla è atomica, così garantisce che nessun altro sarà in grado di selezionare la stessa riga.
Il suggerimento READPAST fa il trucco, un buon articolo http://www.mssqltips.com/sqlservertip/1257/processing-data-queues-in-sql-server-with-readpast-and-updlock/ – newbie
Con SQL 2008 , è possibile utilizzare la clausola OUTPUT con l'avviso READPAST nella query per combinare l'operazione di coda in una singola istruzione.http: //www.sqlservercentral.com/articles/Queue+processing/69653/ – newbie
@newbie Sì, è possibile utilizzare output per bloccare e recuperare i messaggi e contrassegnarli elaborati in una singola query. Ma ho confrontato le prestazioni per l'elaborazione di singoli messaggi e non c'è alcun guadagno rispetto a due query (selezionare prima e poi aggiornare). In realtà il throughput multi-thread era leggermente inferiore quando si utilizzava la query OUTPUT. Forse nell'elaborazione batch la clausola Output sarebbe più veloce, ma per i singoli messaggi non lo è. – nightwatch