SQL Server (2012) non bloccante DDL?
-
22-10-2019 - |
Domanda
Non sono molto esperto con SQL Server, quindi forse mi manca qualcosa
La mia situazione è la seguente:
- Sessione 1 viene eseguito un CREATE TABLE (o altro CREATE) con autocommit spento e il CREATE non viene commesso.
- Sessione 2 esegue un'istruzione
sp_table
ma si blocca finché sessione 1 non sta commettendo il DDL
Lo scenario in cui questo accade è sviluppatori che lavorano sul database. Alcuni di loro navigazione tavoli, alcuni di loro facendo DDL. Se dimentica un utente a commettere il DDL tutte le altre sessioni che vogliono elencare le tabelle sono bloccate. Si noti che il sp_tables
viene emesso esempio dal cliente SQL (tramite il driver JDBC), quindi non è qualcosa che può essere modificato.
Il database su cui sto lavorando con ha snapshot_isolation abilitato e il livello di isolamento è impostato per leggere commesso (SET ALLOW_SNAPSHOT_ISOLATION ON
e SET READ_COMMITTED_SNAPSHOT ON
)
La mia ipotesi è che queste impostazioni dovrebbero fare di SQL Server si comportano meglio per quanto riguarda il blocco in sessioni simultanee (ad esempio, come PostgreSQL e Oracle dove SELECT non sono mai bloccate da qualsiasi scrittore) - ma a quanto pare questo non è il caso.
Quindi, non v'è alcun modo per rendere SQL Server più amichevole nei confronti di lettura / scrittura situazioni concomitanti per quanto riguarda DDL? (A parte la presentazione DDL solo in modalità auto-commit).
Soluzione
No non c'è modo di configurare SQL Server per fare quello che vuoi fare.
Sotto l'isolamento dello snapshot la chiamata a sp_tables
viene bloccato in attesa di una serratura a chiave condivisa su una delle tabelle di base di sistema (sysschobjs
) quando si fa un SELECT
da sys.all_objects
Il Utilizzando argomento di isolamento I livelli delle versioni delle righe basate in BOL fa dire:
SQL Server non mantenere più versioni di metadati di sistema. Dati Definition Language (DDL) dichiarazioni su tavoli e altri database oggetti (indici, viste, i tipi di dati, stored procedure, e comune funzioni Language Runtime) il cambiamento dei metadati.
Anche sotto TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
la chiamata alla estremità sp_tables
per bloccare Tuttavia, mentre il SELECT ... FROM sys.all_objects
dritto in avanti non è più bloccato i riferimenti stessa query HAS_PERMS_BY_NAME
funzione nella clausola WHERE
. Questo sembra avviare una transazione di sistema (CMetadataAccessor::CMetadataAcce
) ad un livello di isolamento più elevato e finisce per ottenere bloccato in attesa di una serratura a chiave condivisa su sysschobjs
di nuovo.
Altri suggerimenti
Un'idea: pianificazione di un lavoro ogni 15 secondi per cercare DDL uncommited inattività e terminare sessioni e li Rool indietro
.