2013-05-14 10 views
10

Lo standard SQL specifica l'ordine di blocco per una query su più tabelle?Cosa determina l'ordine di blocco per una query su più tabelle?

Ad esempio, in:

SELECT department.id FROM permissions, terminals, departments WHERE department.id = ? AND terminal.id = ? AND permissions.parent = department.id AND permissions.child = terminals.id;

  1. Vuol standard SQL garantiscono un ordine di bloccaggio o viene determinata dal piano di esecuzione (attuazione specifiche)?
  2. C'è un modo per garantire un ordine di chiusura?
  3. Se non è possibile garantire l'ordine di blocco, in che modo è possibile impedire i deadlock?

UPDATE: Si prega di non votare per chiudere la questione senza spiegare il tuo ragionamento. Per quanto mi riguarda, questa è una domanda di programmazione, che lo rende molto in tema per StackOverflow. Se ritieni che la domanda debba essere ulteriormente perfezionata, ti preghiamo di spiegare e sarò più che felice di risponderti.

+1

Le query SELECT non generano blocchi che provocano deadlock. Puoi riformulare la tua domanda in modo che sia rilevante per una situazione reale? –

+1

@GordonLinoff, le query SELECT in READ_COMMITTED generano blocchi (ma per la durata dell'istruzione). Per altri livelli di isolamento (come REPEATABLE_READ o SERIALIZABLE) mantengono un blocco fino alla fine della transazione. Avvertenza: alcuni database utilizzano MVCC che non utilizza alcun blocco, ma questi sono fuori dallo scopo di questa domanda. – Gili

+1

I blocchi sono un dettaglio di implementazione. I livelli di isolamento specificano solo i fenomeni che possono/non possono verificarsi. In SQL Server, le query selezionate su read commit richiedono principalmente lock 'S' che vengono rilasciati non appena vengono letti i dati (prima della fine dell'istruzione). A volte questi blocchi possono essere mantenuti fino a quando l'istruzione termina comunque [esempio] (http://blogs.msdn.com/b/craigfr/archive/2007/05/31/read-committed-and-large-objects.aspx) e altre volte non prende affatto le serrature 'S' a livello di riga. E dato il punto 1, i punti 2 e 3 non sono disponibili se non si specifica un particolare RDBMS. –

risposta

5

In base all'ordine di blocco https://stackoverflow.com/a/112256/14731 è determinato dall'ordine di esecuzione specifico dell'implementazione. La risposta prosegue affermando che non esiste un modo deterministico per prevenire i deadlock. Mentre nella programmazione imperativa possiamo prevenire i deadlock acquisendo blocchi nello stesso ordine, sembra che nei sistemi dichiarativi dobbiamo aggirarli riprovando l'operazione quando viene rilevato un deadlock.

Inoltre, sostengo che dal momento che i piani di esecuzione del database cambiano nel corso della loro durata, è tecnicamente impossibile prevenire i deadlock.

+0

Si noti che la frase "quando si accede alle tabelle nello stesso ordine" nella risposta menzionata si riferisce all'ordine delle istruzioni di aggiornamento. L'ordine delle tabelle in una query di join, non avrà molto effetto sulla probabilità di un deadlock, poiché la query crea solo blocchi S. Due transazioni che eseguono la stessa query non si bloccheranno tra loro. – nakosspy

+0

@nakosspy, due transazioni che eseguono la query sullo stesso set di tabelle ma in un ordine diverso potrebbero causare un deadlock (almeno, per un'implementazione del DB ingenuo). In altre parole, sono d'accordo con te sul fatto che l'esecuzione della stessa query non causerà un deadlock, ma il punto è che anche "SELECT" senza un "UPDATE" può causare un deadlock. – Gili

+2

Cosa intendi con un'implementazione ingenua del database? Un DB che acquisisce blocchi esclusivi per una query? Non conosco nessun database che faccia questo. Tuttavia, nel caso in cui si abbia a che fare con un database così "ingenuo", il problema principale sarebbe l'integrità e le prestazioni dei dati, non i deadlock. – nakosspy

1

Posso darvi una risposta per DB2, ma penso che questo dovrebbe essere simile anche per altri database. Prima di tutto, tutto dipende dal parametro di blocco delle tabelle. Questo parametro definisce cosa è bloccato. Puoi avere locksize = table, page o row. Quindi, in base al blocco di ciascuna tabella, il database bloccherà l'oggetto (tabella, pagina o riga) utilizzato per recuperare i dati per il cursore. Pertanto, l'ordine dei blocchi creati verrà specificato dal percorso di accesso, che dipende dall'ottimizzatore.

+0

Quindi stai dicendo che dipende dal piano di esecuzione specifico dell'implementazione? Se è così, e la domanda 3? – Gili

+0

Prima di tutto queste serrature sono serrature S. Ciò significa che nessuna altra transazione è autorizzata ad aggiornare le pagine (o le righe) utilizzate dal cursore. Se apri un cursore e il livello di isolamento viene letto in stabilità, a nessun altro è consentito modificare i dati letti dal cursore. La tua transazione è autorizzata a modificare questi dati. Se si desidera ridurre al minimo i deadlock, preferire il blocco di riga sulla pagina o sulla tabella e impostare il livello di isolamento sulla stabilità del cursore. – nakosspy

Problemi correlati