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).

È stato utile?

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

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top