2012-03-23 14 views
5

Ho una tabella di grandi dimensioni che viene popolata da una vista. Questo perché la visualizzazione impiega molto tempo per essere eseguita ed è più facile avere i dati facilmente disponibili in una tabella. Una procedura viene eseguita ogni tanto che aggiorna la tabella.Blocco tabella durante l'inserimento

TRUNCATE TABLE LargeTable 

INSERT INTO LargeTable 
SELECT * 
FROM viewLargeView 
WITH (HOLDLOCK) 

Vorrei chiudere questa tabella quando si inserisce quindi se qualcuno cerca di selezionare un record non riceveranno nessuno dopo il troncamento. Il blocco che sto usando sembra bloccare la vista e non il tavolo.

C'è un modo migliore per affrontare questo problema?

+1

Che dire di aprire una transazione prima dell'inserto e chiuderla dopo? –

+0

Quando si apre una transazione, un altro utente può selezionare dalla tabella? – JBone

+0

FYI, ti consigliamo di utilizzare DELETE anziché TRUNCATE, poiché TRUNCATE è un DDL, anziché un DML come DELETE e pertanto richiede autorizzazioni maggiori. Inoltre, se lo completi in una Transazione (che è la risposta corretta alla tua domanda), eseguiranno effettivamente lo stesso. – RBarryYoung

risposta

4
BEGIN TRANSACTION t_Transaction 

BEGIN TRY 

TRUNCATE TABLE LargeTable 

INSERT INTO LargeTable 
SELECT * 
FROM viewLargeView 
    WITH (HOLDLOCK) 


COMMIT t_Transaction 

END TRY 

BEGIN CATCH 
    ROLLBACK t_Transaction 
END CATCH 
+0

Non pensare che questo possa fare qualsiasi cosa. Il 'truncate' non è influenzato da una transazione, e un inserto tutto da solo è anche una transazione, anche se non ne specifichi uno. – Andomar

+0

In realtà TRUNCATE viene eseguito il rollback con alcuni avvertimenti. Vedi [this] (http://blog.sqlauthority.com/2007/12/26/sql-server-truncate-cant-be-rolled-back-using-log-files-after-transaction-session-is-closed /) –

4

È vero che il suggerimento di chiusura corretto influisce sulla vista sorgente.

Per fare in modo che nessuno possa leggere dalla tabella, mentre si sta inserendo:

insert into LargeTable with (tablockx) 
... 

Non devi fare nulla per rendere il tavolo sembrare vuota fino a dopo l'inserto completa. Un inserto viene sempre eseguito in una transazione e nessun altro processo può leggere righe non salvate, a meno che non specifichino esplicitamente with (nolock) o set transaction isolation level read uncommitted. Non c'è modo di proteggerlo per quanto ne so.

Problemi correlati