Domanda

Ho un'applicazione VB6 l'accesso a una singola tabella in un server MSSQL2000 tramite ADO. Sto usando l'accesso in sola lettura (adOpenStatic, adLockReadOnly) Ci sono altre applicazioni nella rete che fanno apportare modifiche alla tabella.

Per qualche motivo sto ottenendo gli errori della mia domanda non possa essere scelto come vittima del deadlock.

Sono molto confuso: perché non ci può essere una situazione di stallo in cui io sono solo la lettura da una singola tabella? Mi aspetto timeout, a causa della scrittura delle altre applicazioni, ma non una situazione di stallo ...

Qualcuno può fare luce su questo?

UPDATE: 2009-06-15 Sono ancora interessato a una soluzione a questo problema. Così sto fornendo qualche informazione in più:

  • Non fa differenza se scelgo adOpenForwardOnly o adOpenStatic
  • Non fa differenza se la posizione del cursore è client o server.
È stato utile?

Soluzione

E 'possibile per una singola istruzione SELECT a un punto morto contro un singolo UPDATE o DELETE per la presenza di un indice non cluster, si consideri lo scenario follwing:

Il lettore (la tua app) ottiene prima un blocco condiviso sull'indice non cluster al fine di eseguire una ricerca, e quindi tenta di ottenere un blocco condiviso nella pagina contianing i dati al fine di restituire i dati stessi.

Lo scrittore (altra applicazione) ottiene prima un blocco esclusivo sulla pagina database contenente i dati, e quindi tenta di ottenere un blocco esclusivo sull'indice per aggiornare l'indice.

Si possono trovare maggiori informazioni su questo (e altri) il tipo di stallo in questo articolo Q169960 Microsoft KB ( http://support.microsoft.com/kb/q169960/ )

Inoltre si potrebbe desiderare di dare un'occhiata su Google su come ottenere le informazioni di traccia deadlock (flag di traccia 1222) - questo rapporto su cosa esattamente le istruzioni SQL sono in conflitto su ciò che gli oggetti ogni volta che una situazione di stallo occurrs. Questo è un articolo dall'aspetto abbastanza decente - http: //blogs.msdn .com / bartd / archive / 2006/09/09 / 747119.aspx

Altri suggerimenti

Credo che ci sono una serie di possibilità nelle risposte già fornite qui. Dal momento che si prende solo lock condivisi, la situazione di stallo non può essere a causa di bloccare l'escalation, e deve essere semplicemente l'acquisizione di blocchi che sono incompatibili con quelle acquisite in un altro processo, e l'acquisizione di quelle serrature in un ordine diverso ...

I tuoi blocchi condivisi sono incompatibili con un altro processo che blocchi esclusivi. Lo scenario potrebbe eseguire qualcosa di simile ...

  1. Si prende blocco condiviso sulla risorsa A
  2. Altro processo richiede blocco esclusivo sulla risorsa B
  3. Altro processo tenta di prendere blocco esclusivo sulla risorsa A, e blocca in attesa di rilascia il blocco condiviso su A.
  4. Si tenta di prendere blocco condiviso sulla risorsa B, e potrebbe bloccare in attesa che l'altro processo per rilasciare il suo blocco esclusivo B, solo che ora siete in una situazione di stallo, che viene identificato dal server e si sceglie un processo per uccidere.

NB. deadlock possono avere più giocatori che solo 2. A volte c'è una catena di attività intrecciate che si traduce in una situazione di stallo, ma il principio è lo stesso.

Spesso, se più applicazioni accedono allo stesso database, c'è un DBA che gestisce tutti gli accessi tramite le stored procedure, così da poter garantire le risorse sono sempre bloccate nello stesso ordine. Se non siete in quella situazione, e le altre applicazioni di utilizzare le istruzioni SQL ad-hoc che avrebbe dovuto esaminare il loro codice per scoprire se essi potrebbero entrare in conflitto con la tua applicazione nel modo che ho descritto. Che non suona come divertimento.

Una soluzione pragmatica potrebbe essere quella di catturare l'errore quando la transazione viene ucciso come vittima deadlock, e semplicemente ri-provare la transazione più volte. A seconda di quanto l'attività delle altre applicazioni stanno generando, si potrebbe ottenere risultati accettabili in questo modo.

Legge può ancora incorrere serrature, in modo che il DB per garantire che un isnt scrittura fatta nel bel mezzo di una lettura non atmico. In altre parole il blocco di lettura assicura che si ottiene un accurato snapshot consistente di qualsiasi dato che si sta slecting.

Si ottiene lo stesso comportamento con adOpenForwardOnly?

Si potrebbe voler controllare che le statistiche di SQL Server siano aggiornati. Oppure si potrebbe ottenere il vostro DBA per ricostruire tutti gli indici. Molti problemi sono dovuti alla chiusura di statistiche aggiornate / indici.

Dipende dal comportamento sia dell'applicazione. la vostra applicazione può sicuramente aspettare l'altro per rilasciare le risorse.

Un deadlock si riferisce ad una condizione in cui due o più processi sono in attesa per l'altro per rilasciare una risorsa, o più di due processi sono in attesa di risorse in una catena circolare. Certo si può creare una situazione di stallo con accesso in sola lettura perché la lettura non aspetta.

C'è una bella spiegazione circa le condizioni di deadlock al wikipedia

Non sarebbe qualcosa di simile?

Altro Application : Scrivi a tavola (acquisizione di blocco in scrittura sulla tabella)

delle applicazioni :. Leggi da tavolo (acquisire blocco di lettura sul tavolo, non può a causa di scrivere serratura)

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