(Consumo di risorse, low performance, etc.... )
Le In-Memory Optimized Tables introdotte da SQL Server 2014 CTP1 utilizzano un meccanismo di gestione accessi concorrenziali di tipo Optimistic Multiversion,
che consente alle transazioni di essere Lock e Latch Free.
Ciò non significa assolutamente che le transazioni implementate sulle in-Memory Optimized Tables non siano
Atomic
Consistency
Isolation
Durability
Vediamo un esempio di funzionamento.
Creo un Database di test
Use Master Go CREATE DATABASE Hekaton_Test ON PRIMARY(NAME = [PRIMARY], FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\Hekaton_Test\Hekaton_DiskBasedTable.mdf') ,FILEGROUP [SampleDB_mod_fg] CONTAINS MEMORY_OPTIMIZED_DATA (NAME = [HKDB_mod_dir],FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\Hekaton_Test\In_Memory_Table') LOG ON (name = [SampleDB_log], Filename='C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\Hekaton_Test\Hekaton_Test_log.ldf') Go Use Hekaton_Test Go Create table MemoryTable ( id int not null PRIMARY KEY NONCLUSTERED HASH WITH(BUCKET_COUNT = 1024) ,Campo char(30) not null )WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA); GO ;With Cte as(Select 1 Riga union All Select 1) ,Cte4 as (Select A.Riga From Cte A, Cte B) ,Cte16 as (Select A.Riga From Cte4 A, Cte4 B) ,Cte256 as (Select A.Riga From Cte16 A, Cte16 B) ,Cte65536 as (Select A.Riga From Cte256 A, Cte256 B) ,Results as (Select ROW_NUMBER()Over(Order by Riga) Riga From Cte65536) Insert into MemoryTable(id, Campo) Select Riga ,Riga from Results where Riga <= 1024Simulo l'accesso di due connessioni alla medesima tabella, la prima eseguirà una transazione in update di tutte le righe, la seconda contemporaneamente tenterà la lettura dell'intera tabella.
Questa la transazione
USE Hekaton_Test BEGIN TRANSACTION UPDATE MemoryTable WITH(SNAPSHOT) SET campo = 'T1 ' + campo SELECT * FROM MemoryTable WITH(SNAPSHOT)
N.B. Senza WITH(SNAPSHOT) l'update e la select della prima connessione restituirebbero un errore.
Nella MSDN trovate tutte le info sull'utilizzo degli Isolation Level con le In-Memory Optimized Tables.
La prima transazione è attualmente attiva dato che il COMMIT ancora non è stato implementato.
Cosa succede se la seconda connessione tenta la lettura della tabella ?
SELECT * FROM MemoryTable
Dato che le In-Memory Optimized tables utilizzano un sistema Optimistic Multiversion non ho lock e di conseguenza no wait, quindi i dati vengono restituiti senza attesa nella loro versione pre-modifica.
N.B. Il multiversioning per le In-Memory Optimized Tables non utilizza il TempDb ma la RAM.
Ovviamente chiudendo con il COMMIT la transazione che ha implementato l'update tutte le successive letture restituiranno i dati modificati.
Ma cosa accade quando 2 transazioni tentano di modificare i medesimi dati contemporaneamente ?
Non avendo ancora effettuato il commit posso eseguire subito una nuova transazione che implementerà una modifica.
USE Hekaton_Test BEGIN TRANSACTION UPDATE MemoryTable WITH(SNAPSHOT) SET campo = 'T2 ' + campo SELECT * FROM MemoryTable WITH(SNAPSHOT)
ed ecco il risultato
In casi come questo è necessario ritentare la transazione.
Qui trovate le linee guida per il retry delle transazioni.
Qui trovate le linee guida sulla selezione dell'isolation level.
Ciao
Luca
Nessun commento:
Posta un commento