2011-09-13 11 views
38

Sto usando Entity Framework e sto inserendo record nel nostro database che includono un campo blob. Il campo blob può contenere fino a 5   MB di dati.L'inserimento di dati in SQL Server blocca l'intera tabella?

Quando si inserisce un record in questa tabella, blocca l'intera tabella?

Quindi, se stai interrogando qualsiasi dato dalla tabella, bloccherà fino a quando l'inserimento non sarà completo (mi rendo conto che ci sono dei modi per aggirare questo, ma sto parlando per impostazione predefinita)?

Quanto tempo ci vorrà prima che causi un deadlock? Questo tempo dipenderà dalla quantità di carico presente sul server, ad es. se non c'è molto carico, ci vorrà più tempo per causare un deadlock?

C'è un modo per monitorare e vedere cosa è bloccato in un determinato momento?

Se ogni thread esegue query su singole tabelle, è possibile che si verifichi il blocco? Quindi non è il caso che un deadlock può verificarsi solo se hai una query che ha un join e agisce su più tabelle?

Ciò sta tenendo conto del fatto che la maggior parte del mio codice è solo un insieme di istruzioni selezionate, non un mucchio di transazioni a lungo termine o qualcosa del genere.

risposta

97

Holy cow, hai un sacco di domande qui, heh.Ecco alcune risposte:

Quando si inserisce un record in questa tabella, blocca l'intera tabella?

Non predefinito, ma se si utilizza il suggerimento TABLOCK o se si eseguono determinati tipi di operazioni di caricamento di massa, quindi sì.

Quindi, se si stanno interrogando i dati dalla tabella, si bloccherà fino a quando l'inserimento non sarà completato (mi rendo conto che ci sono dei modi per aggirare questo problema, ma sto parlando per impostazione predefinita)?

Questo diventa un po 'più complicato. Se qualcuno sta provando a selezionare i dati da una pagina nella tabella che hai bloccato, allora sì, li blocchi. È possibile aggirare il problema con cose come l'hint NOLOCK su un'istruzione select o usando l'isolamento di snapshot Committed Read. Per un punto di partenza su come funzionano i livelli di isolamento, controlla Kendra Little's isolation levels poster.

Quanto tempo ci vorrà prima che causi un deadlock? Questo tempo dipenderà dalla quantità di carico presente sul server, ad es. se non c'è molto carico ci vorrà più tempo per causare un deadlock?

I deadlock non sono basati sul tempo: si basano sulle dipendenze. Dire che abbiamo avuto questa situazione:

  • Query A è in possesso di un mazzo di serrature, e compiere la sua interrogazione, ha bisogno di roba che bloccato da query B
  • Query B è anche in possesso di un mazzo di serrature, e per finire la sua interrogazione, ha bisogno di roba che bloccato da query a

Né query può andare avanti (si pensi situazione di stallo messicano) in modo SQL Server chiama un pareggio, spara interrogazione di qualcuno nella parte posteriore, rilascia i suoi riccioli, e lascia andare l'altra query. SQL Server seleziona la vittima in base alla quale sarà meno costoso eseguire il rollback. Se si vuole essere fantasiosi, è possibile utilizzare SET DEADLOCK_PRIORITY LOW su particolari query per dipingere i target sulla loro schiena e SQL Server li scatterà per primi.

C'è un modo per monitorare e vedere cosa è bloccato in un determinato momento?

Assolutamente - ci sono le viste di gestione dinamica (DMV) che puoi eseguire query come sys.dm_tran_locks, ma il modo più semplice è utilizzare Adam Machanic's free sp_WhoIsActive stored proc. E 'una sostituzione davvero chiazza di petrolio per sp_who che si può chiamare in questo modo:

sp_WhoIsActive @get_locks = 1 

Per ogni query in esecuzione, si otterrà un po' di XML che descrive tutti i blocchi in suo possesso. C'è anche una colonna di blocco, quindi puoi vedere chi sta bloccando chi. Per interpretare i blocchi trattenuti, ti consigliamo di controllare lo Books Online descriptions of lock types.

Se ogni thread esegue query su singole tabelle, è possibile che si verifichi il blocco? Quindi non è il caso che un deadlock può verificarsi solo se hai una query che ha un join e agisce su più tabelle?

Che ci crediate o meno, a single query can actually deadlock itself e sì, le query possono bloccarsi su un solo tavolo. Per saperne di più su deadlock, controlla The Difficulty with Deadlocks by Jeremiah Peschka.

+3

Lista di letture impressionante; Grazie! – dividius

+0

Buona forma mio buon uomo .... – dotnetnewb

0

La risposta migliore che riesco a trovare è: dipende.

Il modo migliore per verificare è trovare la connessione SPID e utilizzare sp_lock SPID per verificare se la modalità di blocco è X sul tipo di TAB. Puoi anche verificare il nome della tabella con SELECT OBJECT_NAME(objid). Mi piace anche utilizzare la query qui sotto per verificare il blocco.

SELECT RESOURCE_TYPE,RESOURCE_SUBTYPE,DB_NAME(RESOURCE_DATABASE_ID) AS 'DATABASE',resource_database_id DBID, 
    RESOURCE_DESCRIPTION,RESOURCE_ASSOCIATED_ENTITY_ID,REQUEST_MODE,REQUEST_SESSION_ID, 
    CASE WHEN RESOURCE_TYPE = 'OBJECT' THEN OBJECT_NAME(RESOURCE_ASSOCIATED_ENTITY_ID,RESOURCE_DATABASE_ID) ELSE '' END OBJETO 
    FROM SYS.DM_TRAN_LOCKS (NOLOCK) 
    WHERE REQUEST_SESSION_ID = --SPID here 

In SQL Server 2008 (e versioni successive) è possibile disattivare l'escalation di blocco sul tavolo e far rispettare una CON (ROWLOCK) nella clausola inserto forzando in modo efficace un rowlock. Non è possibile eseguire ciò prima di SQL Server 2008 (è possibile scrivere WITH ROWLOCK, ma SQL Server può scegliere di ignorarlo).

Sto parlando di generali qui e non ho molta esperienza con i BLOB in quanto di solito consiglio agli sviluppatori di evitarli, specialmente se sono più grandi di 1   MB.

3

Se si dispone di un controllo diretto sul SQL, è possibile forzare il blocco a livello di riga utilizzando:

INSERT INTO MyTable(Id, BigColumn) WITH (ROWLOCK) 
VALUES(...) 

Queste due risposte potrebbe essere utile:

Is it possible to force row level locking in SQL Server?

Locking a table with a select in Entity Framework

Per visualizzare i lock correnti in Management Studio, guardare sotto il server, quindi sotto Management/Activity Monitor. Ha una sezione per i blocchi per oggetto, quindi dovresti essere in grado di vedere se gli inserti causano davvero un problema.

+0

Prendere nota, come ho spiegato, senza disabilitare l'escalation del blocco sulla tabella, SQL Server può scegliere di ignorare il suggerimento e inoltrare il blocco in base a diversi fattori. –

+0

Non sapevo quel punto sul comportamento pre-2008 - non avevo visto il tuo post quando ho inviato il mio. Sono d'accordo con il punto di evitare grandi blocchi se possibile. –

0

Gli errori di deadlock generalmente ritornano abbastanza rapidamente. Gli stati di deadlock non si verificano a causa di un errore di timeout che si verifica durante l'attesa di un blocco. Deadlock viene rilevato da SQL Server cercando i cicli nelle richieste di blocco.

Problemi correlati