Domanda

abbiamo un cliente che ha riscontrato alcuni problemi di blocco con la nostra applicazione database.Abbiamo chiesto loro di eseguire una traccia del report del processo bloccato e la traccia che ci hanno fornito mostra il blocco che si verifica tra un'operazione SELECT e UPDATE.I file di traccia mostrano quanto segue:

  • La stessa query SELECT viene eseguita a diversi livelli di isolamento.Una traccia mostra un Serializable IsolationLevel mentre una traccia successiva mostra un RepeatableRead IsolationLevel.Non utilizziamo una transazione esplicita durante l'esecuzione della query.
  • La query UPDATE viene eseguita con un livello di isolamento RepeatableRead ma viene bloccata dalla query SELECT.Ciò è previsto poiché i nostri aggiornamenti sono racchiusi in una transazione esplicita con IsolationLevel di RepeatableRead.

Quindi, in pratica, non sappiamo perché il livello di isolamento della query SELECT non dovrebbe essere il ReadComtched IsolationLevel predefinito ma, in modo ancora più confuso, perché il livello di isolamento della query cambierebbe nel tempo?È solo un cliente a riscontrare questo comportamento, quindi sospettiamo che possa trattarsi di un problema di configurazione del database.

Qualche idea?

Grazie in anticipo,

Graham

È stato utile?

Soluzione

Nel tuo scenario, consiglierei di impostare esplicitamente il livello di isolamento su snapshot, ciò impedirà alla lettura di intralciare le scritture (inserimenti e aggiornamenti) impedendo i blocchi, ma quelle lette sarebbero comunque letture "buone" (ovverodati non sporchi - non è la stessa cosa di un NOLOCK)

Generalmente trovo che quando riscontro problemi di blocco con le mie query, controllo manualmente il blocco applicato.per esempio.Farei aggiornamenti con blocchi a livello di riga per evitare il blocco del livello di pagina/tabella e impostare le mie letture su ReadPast (accettando che potrei perdere alcuni dati, in alcuni scenari che potrebbero essere ok) link | EDIT | ELIME | ELIME | FLAG | FLAG

EDIT-- Combinando tutti i commenti nella risposta

Come parte del processo di ottimizzazione, SQL Server evita di ricevere letture confermate su una pagina che sa non è cambiata e ricorre automaticamente a una strategia di blocco minore.Nel tuo caso, SQL Server passa da una lettura serializzabile a una lettura ripetibile.

Q:Grazie per queste informazioni utili sull'abbassamento dei livelli di isolamento.Riesci a pensare a qualche motivo per cui utilizzerebbe Serializable IsolationLevel in primo luogo, dato che non utilizziamo una transazione esplicita per SELECT: era nostra comprensione che la transazione implicita avrebbe utilizzato ReadComtched?

UN:Per impostazione predefinita, SQL Server utilizzerà Read Commmited se questo è il livello di isolamento predefinito MA se non specifichi inoltre una strategia di blocco nella query, in pratica stai dicendo a SQL Server "fai ciò che ritieni sia meglio, ma la mia preferenza è Leggi Impegnato".Poiché SQL Server è libero di scegliere, lo fa anche per ottimizzare la query.(L'algoritmo di ottimizzazione nel server SQL è molto complesso e non lo capisco appieno da solo).La mancata esecuzione esplicita all'interno di una transazione non influisce, a quanto pare, sul livello di isolamento utilizzato da SQL Server.

Q:Un'ultima cosa: sembra ragionevole che SQL Server aumenti il ​​livello di isolamento (e presumibilmente il numero di blocchi richiesti) per ottimizzare la query?Mi chiedo anche se il riutilizzo di una connessione in pool influirebbe su questo se ereditasse l'ultimo livello di isolamento utilizzato?

UN:Il server SQL lo farà come parte di un processo chiamato "Lock Escalation".Da http://support.microsoft.com/kb/323630, quoto:"Microsoft SQL Server determina dinamicamente quando eseguire l'escalation dei blocchi.Quando si prende questa decisione, SQL Server prende in considerazione il numero di blocchi mantenuti durante una particolare scansione, il numero di blocchi mantenuti dall'intera transazione e la memoria utilizzata per i blocchi nell'intero sistema.In genere, il comportamento predefinito di SQL Server determina un'escalation dei blocchi che si verifica solo nei punti in cui migliorerebbe le prestazioni o quando è necessario ridurre l'eccessiva memoria di blocco del sistema a un livello più ragionevole.Tuttavia, alcune applicazioni o progetti di query potrebbero attivare l'escalation del blocco in un momento in cui non è auspicabile e il blocco della tabella intensificata potrebbe bloccare altri utenti".

Sebbene l'escalation dei blocchi non sia esattamente la stessa cosa della modifica del livello di isolamento con cui viene eseguita una query, questo mi sorprende perché non mi sarei aspettato che SQL Server accettasse più blocchi di quanto consentito dal livello di isolamento predefinito.

Altri suggerimenti

Maggiori informazioni per quanto riguarda il motivo per cui SQL sarebbe voluto più serrature intensificando: questo non è corretto, escalation riduce (non aumenta) il numero di blocchi necessari. Un blocco tabella è un singolo blocco contro tutte le pagine o riga blocchi necessari per fare lo stesso da un livello inferiore. l'escalation dei blocchi è sempre fatto per un motivo: è più efficiente di fare un blocco di livello superiore per bloccare tutti gli oggetti di livello inferiore

Per esempio, forse non v'è alcun indice disponibile per bloccare efficacemente contro. Cioè se si prende un conteggio con UPDLOCK su tutti i record con un anno del 2010 in un campo, e non v'è alcun indice su quel campo data, ciò richiederà un blocco di riga su ogni record nel 2010, che non è efficiente se molti record sono colpiti e un blocco di pagina non aiuterà né dal momento che sono presumibilmente distribuiti casualmente tra le pagine, quindi SQL prende un blocco di tabella. Inoltre, SQL deve anche bloccare altri record di cambiare ad essere per l'anno 2010, mentre l'UPDLOCK si svolge, e senza indice su questo campo per fare un blocco di intervallo, SQL ha altra scelta che prendere un blocco di tabella per evitare che ciò accada . Quest'ultimo punto è uno spesso perdere per chi è nuovo a ottimizzazione:. La consapevolezza che SQL deve anche "proteggere" l'integrità delle query già eseguite nella transazione

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