2012-03-23 9 views
5

ビューからデータを取り込む大きなテーブルがあります。これは、ビューの実行に時間がかかり、テーブルでデータをすぐに使用できるようにするために簡単に実行できるためです。手続きは毎回実行され、テーブルを更新します。挿入中にテーブルをロックする

TRUNCATE TABLE LargeTable 

INSERT INTO LargeTable 
SELECT * 
FROM viewLargeView 
WITH (HOLDLOCK) 

誰かが、彼らは切り捨て後に何を受けていないではないだろうレコードを選択しようとすると、私はそう挿入するときに、このテーブルをロックしたいと思います。私が使用しているロックは、テーブルではなくビューをロックするようです。

この問題にアプローチするより良い方法はありますか?

+1

挿入の前にトランザクションを開いて後で閉じるとどうなりますか? –

+0

トランザクションを開くときに、別のユーザーがテーブルから選択できますか? – JBone

+0

参考:TRUNCATEはDDLで、DELETEのようなDMLではなくDELETEを使用することをお勧めします。したがって、より大きな権限が必要です。さらに、これをトランザクション(これはあなたの質問に対する正解です)にラップすると、効果的に同じことを実行します。 – RBarryYoung

答えて

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

これは何もしないと思ってください。 'truncate'はトランザクションの影響を受けません。また、それを指定しなくても、insert自体はトランザクションでもあります。 – Andomar

+0

実際には、TRUNCATEはいくつかの警告とともにロールバックされます。 [this](http://blog.sqlauthority.com/2007/12/26/sql-server-truncate-cant-be-rolled-back-using-log-files-after-transaction-session-is-closedを参照してください。 /) –

4

正しいロックヒントがソースビューに影響することは間違いありません。

insert into LargeTable with (tablockx) 
... 

をあなたがテーブルの挿入が完了するまでの空に見えるようにするために何かをする必要はありません:あなたが挿入している間、誰もがテーブルから読み取ることができないようにそれを作るために

。挿入は常にトランザクション内で実行され、明示的にwith (nolock)またはset transaction isolation level read uncommittedを指定しない限り、他のプロセスはコミットされていない行を読み取ることができません。私が知る限り、それを守る方法はありません。

関連する問題