Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il controllo delle versioni delle righe nelle tabelle basate su disco (usando l'isolamento SNAPSHOT o READ_COMMITTED_SNAPSHOT) fornisce una forma di controllo della concorrenza ottimistica. I lettori e gli scrittori non si bloccano tra di loro. Con le tabelle ottimizzate per la memoria, gli scrittori non bloccano gli scrittori. Con il controllo delle versioni delle righe nelle tabelle basate su disco, una transazione blocca la riga e le transazioni simultanee che tentano di aggiornare la riga vengono bloccate. Non c'è blocco con le tabelle ottimizzate per la memoria. Se invece due transazioni tentano di aggiornare la stessa riga, si verificherà un conflitto di scrittura (errore 41302).
A differenza delle tabelle basate su disco, le tabelle ottimizzate per la memoria consentono il controllo della concorrenza ottimistica con i livelli di isolamento più elevati, REPEATABLE READ e SERIALIZABLE. I blocchi non vengono eseguiti per applicare i livelli di isolamento. Invece, alla fine della convalida della transazione, garantisce le ipotesi di lettura ripetibile o di serializzabilità. Se i presupposti vengono violati, la transazione viene terminata. Per altre informazioni, vedere Livelli di isolamento delle transazioni.
La semantica delle transazioni importante per le tabelle ottimizzate per la memoria è:
Versionamento multiplo
Isolamento delle transazioni basato su snapshot
Ottimistico
Rilevamento dei conflitti
Ognuna di queste semantiche è illustrata nelle sezioni seguenti.
Versionamento multiplo nelle tabelle Memory-Optimized
Le righe nelle tabelle ottimizzate per la memoria possono avere versioni diverse. Le transazioni simultanee accedono a versioni potenzialmente diverse della stessa riga.
I dati delle tabelle ottimizzate per la memoria si basano sulle versioni. Per qualsiasi riga possono essere presenti versioni di riga diverse valide in momenti diversi. Le tabelle basate su disco mantengono versioni di riga differenti quando READ_COMMITTED_SNAPSHOT o ALLOW_SNAPSHOT_ISOLATION sono attivi. Le tabelle ottimizzate per la memoria mantengono versioni di riga diverse, anche se READ_COMMITTED_SNAPSHOT e ALLOW_SNAPSHOT_ISOLATION sono OFF. Le versioni di riga delle tabelle ottimizzate per la memoria non vengono mantenute in tempdb. Le versioni delle righe vengono invece mantenute in linea, come parte delle strutture di dati ottimizzate per la memoria che archiviano le righe in memoria.
isolamento delle transazioni Snapshot-Based per le tabelle di Memory-Optimized
Tutte le operazioni in una singola transazione usano lo stesso snapshot coerente transazionale delle tabelle ottimizzate per la memoria. Tutto l'isolamento delle transazioni per le tabelle ottimizzate per la memoria è basato su snapshot. Ad esempio, una transazione che usa il livello di isolamento serializzabile per accedere alle tabelle ottimizzate per la memoria eseguirà tutte le operazioni sullo stesso snapshot coerente a livello di transazione.
Le transazioni che accedono alle tabelle ottimizzate per la memoria usano questo versionamento delle righe per ottenere un'istantanea transazionalmente coerente delle righe nelle tabelle. I dati letti da qualsiasi istruzione della transazione saranno la versione transazionalmente coerente dei dati esistenti al momento dell'avvio della transazione. Pertanto, tutte le modifiche apportate dalle transazioni in esecuzione simultanea non sono visibili alle istruzioni nella transazione corrente.
Controllo ottimistico della concorrenza per le tabelle Memory-Optimized
I conflitti e gli errori sono rari e le transazioni nelle tabelle ottimizzate per la memoria presuppongono che non siano presenti conflitti con transazioni e operazioni simultanee. Le transazioni non accettano blocchi o latch nella tabella ottimizzata per la memoria per garantire l'isolamento delle transazioni. Gli scrittori non bloccano i lettori. Gli scrittori non bloccano gli scrittori. Al contrario, le transazioni proseguono nell'ipotesi (ottimistica) che non ci saranno conflitti con altre transazioni. Non usare blocchi e latch e non attendere che altre transazioni terminino l'elaborazione delle stesse righe migliorano le prestazioni.
Inoltre, se una transazione (TxA) legge righe che sono state inserite o modificate da un'altra transazione (TxB) che è in fase di commit, assumerà in modo ottimistico che l'altra transazione verrà completata piuttosto che attendere che ciò avvenga. In questo caso, la transazione TxA assumerà una dipendenza di commit dalla transazione TxB.
Verifiche di rilevamento dei conflitti, convalida e dipendenze per il commit
SQL Server rileva i conflitti tra le transazioni simultanee, nonché le violazioni del livello di isolamento, e annullerà una delle transazioni in conflitto. Questa transazione dovrà essere ritentata. Per altre informazioni, vedere Linee guida per la logica di ripetizione dei tentativi per le transazioni nelle tabelle Memory-Optimized.
Il sistema presuppone ottimisticamente che non vi siano conflitti e nessuna violazione dell'isolamento delle transazioni. Se si verificano conflitti che possono causare incoerenze nel database o che potrebbero violare l'isolamento delle transazioni, questi conflitti vengono rilevati e la transazione viene terminata.
Se viene rilevato un conflitto, la transazione viene terminata e il client deve riprovare.
La tabella seguente riepiloga le condizioni di errore per le transazioni che accedono alle tabelle ottimizzate per la memoria.
Condizioni di errore per le transazioni che accedono a tabelle ottimizzate per la memoria.
| Errore | Sceneggiatura |
|---|---|
| Conflitto durante la scrittura. Tentativo di aggiornare un record aggiornato dall'avvio della transazione. | UPDATE o DELETE una riga che è stata aggiornata o eliminata da una transazione simultanea. |
| Fallimento di convalida di lettura ripetibile. | Una riga letta dalla transazione è stata modificata (aggiornata o eliminata) dall'avvio della transazione. La convalida di lettura ripetibile viene in genere eseguita quando si usano livelli di isolamento delle transazioni REPEATABLE READ e SERIALIZABLE. |
| Errore di convalida serializzabile. | Dopo l'avvio della transazione è stata inserita una nuova riga (fantasma) in uno degli intervalli di analisi della transazione. La riga sarebbe stata visibile alla transazione se la riga fosse stata sottoposta a commit nel database prima dell'avvio della transazione. La convalida SERIALIZABLE avviene tipicamente quando si utilizzano l'isolamento SERIALIZABLE e si convalidano i vincoli di chiave primaria. |
| Fallimento della dipendenza di commit. | La transazione ha assunto una dipendenza da un'altra transazione che non è riuscita a eseguire il commit, a causa di uno degli errori in questa tabella, di una condizione di memoria insufficiente o a causa di un errore di commit nel log delle transazioni. Questo errore può verificarsi sia con transazioni di lettura/scrittura che di sola lettura. |
Durata delle transazioni
Gli errori indicati nella tabella precedente possono verificarsi in punti diversi durante una transazione. La figura seguente illustra le fasi di una transazione che accede alle tabelle ottimizzate per la memoria.
Durata di una transazione che accede alle tabelle ottimizzate per la memoria.
Elaborazione regolare
Durante questa fase vengono eseguite le istruzioni Transact-SQL rilasciate dall'utente. Le righe vengono lette dalle tabelle e le nuove versioni di riga vengono scritte nel database. La transazione è isolata da tutte le altre transazioni simultanee. La transazione usa lo snapshot delle tabelle ottimizzate per la memoria presenti all'inizio della transazione.
Le scritture nelle tabelle in questa fase della transazione non sono ancora visibili ad altre transazioni, con un'eccezione: gli aggiornamenti delle righe e le eliminazioni sono visibili per aggiornare ed eliminare le operazioni in altre transazioni, per rilevare i conflitti di scrittura.
Se un'operazione di aggiornamento o eliminazione rileva che una riga è stata aggiornata o eliminata dall'inizio logico della transazione, l'operazione avrà esito negativo con errore 41302. Il messaggio di errore 41302 è "La transazione corrente ha tentato di aggiornare un record nella tabella X aggiornata dall'avvio della transazione. La transazione è stata interrotta."
Questo errore condanna la transazione (anche se XACT_ABORT è OFF), il che significa che la transazione verrà annullata quando la sessione utente termina. Le transazioni in fallimento non possono essere confermate e supportano solo operazioni di lettura che non scrivono nel log e non accedono alle tabelle ottimizzate per la memoria.
Dipendenze di commit
Durante l'elaborazione normale, una transazione può leggere righe scritte da altre transazioni che si trovano nella fase di convalida o commit, ma non hanno ancora eseguito il commit. Le righe sono visibili perché l'ora di fine logica delle transazioni è stata assegnata all'inizio della fase di convalida.
Se una transazione legge tali righe di cui non è stato eseguito il commit, verrà eseguita una dipendenza di commit da tale transazione. Ciò ha due implicazioni principali:
Una transazione non può essere completata finché tutte le transazioni da cui dipende non sono state finalizzate. In altre parole, non può entrare nella fase di commit, fino a quando tutte le dipendenze non sono state cancellate.
Inoltre, i set di risultati non vengono restituiti al client finché tutte le dipendenze non vengono cancellate. Ciò impedisce al client di osservare i dati di cui non è stato eseguito il commit.
Se una delle transazioni dipendenti non riesce a eseguire il commit, si verifica un errore di dipendenza del commit. Ciò significa che il commit della transazione non verrà eseguito con l'errore 41301 ("Una transazione precedente su cui la transazione corrente ha avuto una dipendenza è stata interrotta e la transazione corrente non può più eseguire il commit".
Fase di convalida
Durante la fase di convalida, il sistema verifica che i presupposti necessari per il livello di isolamento delle transazioni richiesto siano stati veri tra l'inizio logico e la fine logica della transazione.
All'inizio della fase di convalida, alla transazione viene assegnata un'ora di fine logica. Le versioni di riga scritte nel database diventano visibili ad altre transazioni al momento logicamente di fine. Per ulteriori informazioni, consultare Commit Dependencies.
Convalida di lettura ripetibile
Se il livello di isolamento della transazione è REPEATABLE READ o SERIALIZABLE oppure se le tabelle sono accessibili con isolamento REPEATABLE READ o SERIALIZABLE (per altre informazioni, vedere la sezione Isolamento delle singole operazioni nei livelli di isolamento delle transazioni), il sistema verifica che le letture siano ripetibili. Ciò significa che convalida che le versioni delle righe lette dalla transazione siano ancora versioni di riga valide alla fine logica della transazione.
Se una delle righe è stata aggiornata o modificata, la transazione non riesce a eseguire il commit con errore 41305 ("La transazione corrente non è riuscita a eseguire il commit a causa di un errore di convalida di lettura ripetibile).
Questo errore può verificarsi anche se una tabella viene eliminata dopo un'operazione di inserimento, aggiornamento o eliminazione e prima del commit della transazione. Questo vale solo per le operazioni di inserimento, aggiornamento o eliminazione nelle stored procedure compilate in modo nativo. Tali operazioni di scrittura interpretate tramite Transact-SQL causano il blocco dell'istruzione DROP TABLE, che attende fino al completamento della transazione.
Validazione serializzabile
La convalida serializzabile viene eseguita in due casi:
Se il livello di isolamento della transazione è SERIALIZABLE o le tabelle sono accessibili con isolamento SERIALIZABLE.
Se le righe vengono inserite in un indice univoco, ad esempio l'indice creato per un vincolo PRIMARY KEY. Il sistema verifica che nessuna riga con la stessa chiave sia stata inserita contemporaneamente.
Il sistema verifica che nel database non siano state scritte righe fantasma. Le operazioni di lettura eseguite dalla transazione vengono valutate per determinare che non sono state inserite nuove righe negli intervalli di analisi di queste operazioni di lettura.
L'inserimento di una chiave in un indice univoco include un'operazione di lettura implicita per determinare che la chiave non è un duplicato. La convalida serializzabile per gli indici univoci garantisce che questi indici non abbiano duplicati nel caso in cui due transazioni inseriscano contemporaneamente la stessa chiave.
Se vengono rilevate righe fantasma, la transazione non riesce a eseguire il commit con errore 41325 ("La transazione corrente non è riuscita a eseguire il commit a causa di un errore di convalida serializzabile).
Elaborazione commit
Se la convalida ha esito positivo e tutte le dipendenze delle transazioni sono chiare, la transazione entra nella fase di elaborazione del commit. Durante questa fase le modifiche alle tabelle durevoli vengono scritte nel log e il log viene scritto su disco per garantire la durabilità. Dopo che il record di log per la transazione è stato scritto su disco, il controllo viene restituito al client.
Tutte le dipendenze di commit di questa transazione sono state eliminate e tutte le transazioni che erano in attesa che questa transazione venisse completata possono procedere.
Limitazioni
Le transazioni tra database non sono supportate con tabelle ottimizzate per la memoria. Ogni transazione che accede a tabelle ottimizzate per la memoria non può accedere a più di un database, ad eccezione dell'accesso in lettura/scrittura a tempdb e all'accesso in sola lettura al database master del sistema.
Le transazioni distribuite non sono supportate con tabelle ottimizzate per la memoria. Le transazioni distribuite avviate con BEGIN DISTRIBUTED TRANSACTION non possono accedere alle tabelle ottimizzate per la memoria.
Le tabelle ottimizzate per la memoria non supportano il blocco. I blocchi espliciti tramite hint di blocco (ad esempio TABLOCK, XLOCK, ROWLOCK) non sono supportati con tabelle ottimizzate per la memoria.
Vedere anche
Informazioni sulle transazioni nelle tabelle Memory-Optimized