2010-01-05 87 views
1

使用SQL2k5,我有一個臨時表,其中包含將填充許多其他表的列。例如,像這樣的語句:TSQL快照隔離

INSERT INTO [appTable1] ([colA], [colB]) 
SELECT [appTable1_colA], [appTable1_colB] 
FROM [stageTable] 

在[appTable1]然後將填充新插入的行的標識列的值返回到[stageTable]的觸發器;對於這個例子,我們會說它是[stageTable]。[appTable1_ID],然後將其作爲FK插入到其他表中。更多類似的聲明如下:

INSERT INTO [appTable2] ([colA], [colB], [colC], [appTable1_FK]) 
SELECT [appTable2_colA], [appTable2_colB], [appTable2_colC], [appTable1_ID] 
FROM [stageTable] 

該過程繼續通過許多這樣的表。正如你所看到的,我沒有在臨時表的SELECT中包含一個WHERE子句,因爲這個表在過程結束時被截斷了。但是,這會使另一個進程在該事務處理中向該登臺表添加記錄的可能性,並且這些記錄不會包含先前填充的FK。我想發出此聲明,以防止這個?:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT 

如果這是最好的解決辦法,有什麼做這種方式的缺點?

回答

1

您可以向暫存表中添加批次ID,以便您可以在where子句中使用它以確保您只處理源最後一批記錄?任何將記錄添加到登臺表的進程都必須使用新的唯一批號。我認爲,這會比取決於快照隔離更有效率(更強大)。

+0

我認爲這是我的最佳課程。謝謝。 – heath 2010-01-06 17:33:16

1

所有隔離級別(包括快照)僅影響讀取。來自stageTable的SELECT不會看到未被插入的內容,也不會被阻塞。我不確定這是否解決了將所有內容投入舞臺表而不考慮所有權的問題。當事務最終提交時會發生什麼,stageTable剩下所有中間結果,準備被下一個事務讀取?也許你應該使用一個臨時的#stageTable來確保concurnt線程之間的自然隔離。

要了解使用快照隔離的成本,讀Row Versioning Resource Usage

  • 在tempdb消耗額外的空間
  • 在數據表中的每一行中消耗
  • 額外的空間在BLOB存儲
  • 額外的空間消耗大字段
+0

謝謝你,這是有幫助的,並說服我使用隔離級別不是我的解決方案 – heath 2010-01-06 17:32:38