Domanda

Il codice (sterilizzata) seguendo a volte produce questi errori:

  

Non è possibile eliminare la tabella 'database.dbo.Table', perché non esiste o non si dispone dell'autorizzazione.
  C'è già un oggetto denominato 'tabella' nel database.

begin transaction  
    if exists (select 1 from database.Sys.Tables where name ='Table') 
        begin drop table database.dbo.Table end 

    Select top 3000 *
    into database.dbo.Table
    from OtherTable
commit

select * from database.dbo.Table

Il codice può essere eseguito più volte contemporaneamente. Qualcuno sa perché si rompe?

È stato utile?

Soluzione

In quale parte del codice sta impedendo accessi multipli a questa risorsa?

begin transaction  
    if exists (select 1 from database.Sys.Tables where name ='Table') 
        begin drop table database.dbo.Table end 

    Select top 3000 *
    into database.dbo.Table
    from OtherTable
commit

Begin transazione non lo sta facendo. E 'solo la creazione di uno scenario commit / rollback su tutte le righe aggiunte alle tabelle.

L'(se esiste, drop) è una condizione di competizione, insieme con la ri-creazione del tavolo con (select..into). persone Mutiliple cadere in quel codice di tutto in una volta sarà certamente causare tutti i tipi di errori. Alcuni creazione di tabelle che gli altri hanno appena distrutto, altri cadono le tabelle che non esistono più, e altri cadere tabelle che alcuni sono inserimento occupato in. UGH!

Considerate le suggestioni tabella temporanea degli altri, o utilizzando un blocco dell'applicazione per bloccare altri di entrare questo codice a tutti se la risorsa critica è occupato. Operazioni su goccia / creano non sono ciò che si desidera.

Altri suggerimenti

Posso chiedere perché il vostro fare questo prima? Si dovrebbe considerare l'utilizzo di tabelle temporanee o venire con un'altra soluzione.

Non sono positivo che statments DDL si comportano sameway in operazioni come istruzioni DML e hanno visto un post sul blog con un comportamento strano e la creazione di stored procedure all'interno di un DDL.

Asside dal che si potrebbe desiderare per verificare il livello di isolamento delle transazioni e impostarlo su serializzato.

Modifica

In base a un test rapido, ho eseguito lo stesso sql in due diverse connessioni, e quando ho creato il tavolo, ma non ho commesso l'operazione, la seconda operazione bloccato. Quindi sembra che questo dovrebbe funzionare. Vorrei ancora in guardia contro questo tipo di disegno.

Se si sta solo utilizzando questa tabella durante questo processo vi suggerirei di usare una tabella temporanea o, a seconda della quantità di dati, una tabella di ram. Io uso le tabelle ram frequentemente per evitare eventuali costi di transazione e risparmiare sulle attività del disco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top