2013-07-18 11 views
5

Suppongo che la mia query di aggiornamento è simile al seguente:sql server-Quando ha tabella ottenere bloccato quando l'aggiornamento con unirsi

UPDATE a SET 
    a.colSomething= 1 
FROM tableA a WITH (NOLOCK) 
INNER JOIN tableB b WITH (NOLOCK) 
     ON a.colA= b.colB 
INNER JOIN tableC c WITH (NOLOCK) 
     ON c.colC= a.colA 

Diciamo che quanto sopra si unisce al tableB e TableC richiede diversi minuti per completare. In termini di blocco tabella/riga, l'intera tabella viene bloccata durante l'unione? Oppure il compilatore sql è abbastanza intelligente da evitare di bloccare l'intero tavolo?

E rispetto alla query di cui sopra, è meno probabilità di ottenere deadlock memorizzando il risultato dei join in una tabella temporanea prima l'aggiornamento vero e proprio, come la seguente?

SELECT a, b, c 
INTO  
FROM tableA 
INNER JOIN tableB b WITH (NOLOCK) 
    ON a.colA= b.colB 
INNER JOIN tableC c WITH (NOLOCK) 
    ON c.colC= a.colA 

UPDATE a SET a.colSomething=1 
FROM tableA a INNER JOIN #tmp t ON a.colA= t.colA 

Grazie!

+5

È molto più complesso di quello che stai facendo. Probabilmente hai bisogno di passare un po 'di tempo a leggere [questo articolo] (http://msdn.microsoft.com/en-us/library/jj856598.aspx). –

+0

Ma a livello superiore, penso che ci dovrebbe essere una spiegazione sull'approccio di SQL Server a un aggiornamento del genere? Ho cercato sul Web ma non ho trovato una buona risorsa per questo. Ma il tuo link fornisce una copertura eccellente sulle serrature. –

+0

Non utilizzare WITH (NOLOCK) qui. Stai chiedendo letture sporche, che è l'opposto del ** più sicuro ** che stai mirando. – criticalfix

risposta

3

blocco contro blocco morti

penso che potrebbe essere fonte di confusione di bloccaggio e bloccando con deadlock.

Su qualsiasi query di aggiornamento, il server SQL bloccherà i dati coinvolti. Mentre questo blocco è attivo, altri processi verranno bloccati (ritardati) dalla modifica dei dati. Se l'aggiornamento originale richiede molto tempo (dal punto di vista degli utenti 'come pochi secondi), il sistema front-end potrebbe sembrare "sospeso" o addirittura interrompere il timeout di un processo front-end degli utenti e segnalare un errore.

Questo non è un punto morto. Questo blocco si risolverà da solo, fondamentalmente in modo non distruttivo, ritardando leggermente l'utente o, in alcuni casi, costringendo il front end a essere intelligente riguardo al timeout. Nel problema si verifica il blocco a causa di lunghi aggiornamenti in esecuzione, è possibile correggere gli utenti che devono reinviare aumentando il timeout di front-end.

Un deadlock tuttavia non può essere risolto indipendentemente da quanto si aumenta il timeout. Uno o i processi saranno terminati con pregiudizio (perdita dell'aggiornamento).

I deadlock hanno cause di origine diversa rispetto al blocco. I deadlock sono solitamente causati da una logica sequenziale inconsistente nel front-end, che accede e blocca i dati da due tabelle in ordini diversi in due parti diverse del front-end. Quando queste due parti operano simultaneamente in un ambiente multiutente possono fondamentalmente, non deterministicamente, causare deadlock e essenzialmente perdita di dati irrisolvibili (fino a quando la causa dei deadlock non viene risolta) rispetto al blocco che di solito può essere affrontato.

Gestione bloccando

SQL server sceglierà blocchi di riga o tutto il blocco di tabella?

Generalmente, dipende e potrebbe essere diverso ogni volta. A seconda del numero di righe che determina il determinatore della query, il blocco potrebbe essere riga o tabella. Se supera una certa soglia, andrà a tavola perché sarà più veloce.

Come posso ridurre il blocco mentre si aderisce ai principi di base dell'integrità della transazione?

Il server SQL tenterà di bloccare le tabelle a cui ci si sta unendo perché il loro contenuto è materiale per generare il set di risultati che viene aggiornato. Dovresti essere in grado di mostrare un piano di esecuzione stimato per l'aggiornamento per vedere cosa sarà bloccato in base alla dimensione attuale delle tabelle. Se il blocco previsto è tabella, è possibile eseguire l'override, magari con il suggerimento di blocco riga, ma ciò non garantisce il blocco. Può ridurre la possibilità di blocco involontario di dati non correlati nella tabella. In pratica, si ottiene sempre il blocco dei dati direttamente dal materiale per l'aggiornamento.

Tuttavia, tenere presente;

Inoltre, tenere presente che i blocchi eseguiti sulla tabella unita saranno blocchi condivisi. Il che significa che altri processi possono ancora leggere da quelle tabelle, ma non possono aggiornarli, fino a quando l'aggiornamento non viene fatto usando come riferimento. Al contrario, altri processi bloccheranno attivamente il tentativo di leggere semplicemente i dati che si aggiornano con un blocco esclusivo (la tabella principale viene aggiornata).

Quindi, la tabella unita può ancora essere letta. I dati da aggiornare saranno bloccati esclusivamente come un gruppo di record fino a quando gli aggiornamenti non saranno completi o falliranno e verranno ripristinati come gruppo.

+0

Grazie per la spiegazione. Sì, stavo cercando in che modo la dichiarazione di aggiornamento sopra causerà il blocco non necessario ... Mi chiedevo se SQL Server utilizzerà il blocco riga o il blocco tabella per lo scenario di join sopra? –

+0

È tutto in quell'articolo, ma in generale, dipende e potrebbe essere diverso ogni volta. A seconda del numero di righe che determina il determinatore della query, il blocco potrebbe essere riga o tabella. Se supera una certa soglia, andrà a tavola perché sarà più veloce. –

+0

Inoltre, mettendo tutti i dati in una tabella esterna si sta vanificando lo scopo del motore di blocco. Stai prendendo le tue decisioni sulla concorrenza, in un modo molto specifico. Un modo che è sicuramente rappresentato meglio utilizzando i suggerimenti di blocco esistenti e i livelli di isolamento. –

0

Vorrei inserire indici sulle chiavi esterne, può velocizzare le operazioni di aggiornamento ed eliminazione e alleviare la situazione di deadlock.

Problemi correlati