Blocco dei cursori
In Microsoft SQL Server 2005 l'istruzione SELECT inclusa in una definizione di cursore è soggetta alle stesse regole per il blocco delle transazioni valide per tutte le altre istruzioni SELECT. Nei cursori è tuttavia possibile acquisire un set di blocchi di scorrimento aggiuntivo basato sulla specifica di un livello di concorrenza per il cursore.
I blocchi di transazione acquisiti da un'istruzione SELECT, inclusa l'istruzione SELECT in una definizione di cursore, sono controllati dagli elementi seguenti:
- Impostazione del livello di isolamento della transazione per la connessione.
- Tutti gli hint di blocco specificati nella clausola FROM.
Tali blocchi vengono mantenuti attivi fino al completamento della transazione corrente sia per i cursori che per le istruzioni SELECT indipendenti. Nella modalità autocommit di SQL Server ogni istruzione SQL corrisponde a una transazione e i blocchi vengono rilasciati al termine dell'istruzione. Nella modalità transazione implicita o esplicita di SQL Server i blocchi vengono mantenuti attivi fino all'esecuzione del commit o del rollback della transazione.
Il blocco definito nei due esempi Transact-SQL seguenti è sostanzialmente lo stesso:
/* Example 1 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
SELECT * FROM AdventureWorks.Sales.Store;
GO
/* Example 2 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
DECLARE abc CURSOR STATIC FOR
SELECT * FROM AdventureWorks.Sales.Store;
GO
OPEN abc
GO
Se si imposta il livello di isolamento della transazione su Repeatable Read, sia l'istruzione SELECT indipendente dell'esempio 1 che l'istruzione SELECT inclusa nell'istruzione DECLARE CURSOR dell'esempio 2 genereranno blocchi condivisi in ogni riga letta. Tali blocchi verranno inoltre mantenuti attivi fino all'esecuzione del commit o del rollback della transazione.
Acquisizione di blocchi
Sebbene i cursori siano soggetti alle stesse regole delle istruzioni SELECT indipendenti in relazione al tipo di blocchi acquisiti, l'acquisizione dei blocchi avviene in momenti diversi. I blocchi generati da un'istruzione SELECT indipendente o da un cursore vengono sempre acquisiti durante il recupero di una riga. Nel caso di un'istruzione SELECT indipendente tutte le righe vengono recuperate durante l'esecuzione dell'istruzione. Il recupero delle righe avviene tuttavia a intervalli diversi a seconda del tipo di cursore.
- I cursori statici recuperano l'intero set di risultati all'apertura del cursore. Tale comportamento implica il blocco di tutte le righe di un set di risultati all'apertura.
- I cursori gestiti da keyset recuperano le chiavi di tutte le righe di un set di risultati all'apertura del cursore. Tale comportamento implica il blocco di tutte le righe di un set di risultati all'apertura.
- I cursori dinamici, compresi i normali cursori forward-only, recuperano le righe solo quando viene eseguita l'operazione di recupero. I blocchi vengono acquisiti sulle righe solo al termine dell'operazione di recupero.
- I cursori fast forward-only acquisiscono i blocchi in momenti diversi a seconda del piano di esecuzione scelto da Query Optimizer. Se il piano di esecuzione è dinamico, non verrà applicato alcun blocco finché non saranno state recuperate le righe. Se vengono generate tabelle di lavoro, le righe verranno lette in queste tabelle e bloccate all'apertura.
I cursori supportano inoltre le specifiche di concorrenza, alcune delle quali implicano la generazione di blocchi aggiuntivi sulle righe per ogni operazione di recupero. Tali blocchi di scorrimento vengono mantenuti attivi fino all'operazione di recupero successiva o alla chiusura del cursore, a seconda di quale dei due eventi si verifica per primo. Se è stata attivata l'opzione di connessione per mantenere i cursori aperti nel corso di un'operazione di commit, tali blocchi rimarranno aperti durante il commit o il rollback.