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

Utilizzo di SQL Server come meccanismo di blocco delle risorse

In pratica stai descrivendo un flusso di lavoro classico basato sulla coda e dovresti considerare l'utilizzo di un vero coda .

Per motivi di discussione, ecco come ottenere ciò che desideri:

  • risorsa specifica richiesta:SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK) WHERE key = @key . Si bloccherà se la risorsa è già stata rivendicata. Usa i timeout di blocco per restituire un'eccezione se la risorsa è già stata rivendicata. key deve essere indicizzato e unico.
  • prossima risorsa disponibile:SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK, READPAST) ORDER BY <accessorder> . Devi definire un ordine per esprimere la preferenza delle risorse (la più vecchia, la priorità più alta, ecc.)
  • rilascia una risorsa rivendicata:COMMIT la tua transazione.

L'essenza del problema è l'utilizzo dei suggerimenti di blocco corretti e questo tipo di problema richiede suggerimenti di blocco espliciti per essere risolto. UPDLOCK fungerà da blocco "rivendicazione". ROWLOCK crea la giusta granularità impedendo al server di "ottimizzare" un blocco di pagina. READPAST ti consente di saltare le risorse richieste. L'inserimento di UPDLOCK sulle righe bloccherà la riga e ti consentirà di aggiornarla in un secondo momento, ma impedirà altre operazioni come i normali SELECT con commit di lettura che si bloccheranno sulla riga bloccata. L'idea è però che aggiornerai comunque la riga, il che posizionerà un inevitabile blocco X. Se vuoi mantenere la tabella più disponibile puoi utilizzare blocchi delle app invece, ma è significativamente più difficile da eseguire correttamente. Dovrai richiedere un blocco dell'app su un descrittore di stringa della risorsa, come il valore della chiave, o un CHECKSUM della chiave o è %%LOCKRES%% valore. I blocchi dell'app ti consentono di separare l'ambito della "rivendicazione" da una transazione richiedendo il blocco dell'app nell'ambito della "sessione", ma poi devi rilasciare la richiesta manualmente (i blocchi delle app con ambito "transazione" vengono rilasciati al momento del commit) . Attenzione però, ci sono mille modi per spararti ai piedi con i blocchi delle app.