2008-10-30 27 views
1

我有一個很長的運行插入事務,將數據插入到幾個相關的表中。哪個SQL讀取TRANSACTION ISOLATION LEVEL是否需要長時間運行插入?

當此插入運行時,我無法從MainTable執行select *。選擇只是旋轉其輪子,直到插入完成。

我將在相同/重疊的時間執行其中幾個插入。爲了檢查信息沒有被插入兩次,我首先查詢MainTable以查看是否存在條目並且未處理位被設置。

在插入事務期間,它翻轉該行的MainTable處理位。

所以我需要能夠讀取表格,並且能夠判斷當前是否正在更新特定行。

有關如何在Microsoft SQL 2005中進行設置的任何想法?我正在瀏覽SET TRANSACTION ISOLATION LEVEL文檔。

謝謝
基思

編輯:我不認爲在相同的插入一批將在同一時間發生。這些是正在處理的二進制文件,並將其數據插入到數據庫中。在我解析並插入數據之前,我檢查該文件是否未處理。當我執行檢查時,如果在執行將處理位設置爲false的快速插入MainTable之前沒有看到文件。

有沒有辦法鎖定正在更新的行而不是整個表?

回答

2

您可能需要您使用讀取未提交之前重新考慮你的過程。孤立交易有很多很好的理由。如果您使用READ UNCOMMITTED,則可能仍會得到重複項,因爲插入項有可能會同時檢查更新,並且都沒有找到它們來創建重複項。嘗試分解成較小的批次或發出定期提交

編輯

您可以在一個事務包裹MainTable更新,將騰出表更快,但你仍然可以得到與其他表衝突。

BEGIN TRANSACTION 

SELECT @ProcessedBit = ProcessedBit FROM MainTable WHERE ID = XXX 

IF @ProcessedBit = False 
    UPDATE MainTable SET ProcessedBit = True WHERE ID = XXX 

COMMIT TRANSACTION 

IF @ProcessedBit = False 
BEGIN 
    BEGIN TRANSACTION 
    -- start long running process 
    ... 
    COMMIT TRANSACTION 
END 

編輯啓用錯誤恢復

BEGIN TRANSACTION 

SELECT @ProcessedStatus = ProcessedStatus FROM MainTable WHERE ID = XXX 

IF @ProcessedStatus = 'Not Processed' 
    UPDATE MainTable SET ProcessedBit = 'Processing' WHERE ID = XXX 

COMMIT TRANSACTION 

IF @ProcessedStatus = 'Not Processed' 
BEGIN 
    BEGIN TRANSACTION 
    -- start long running process 
    ... 

    IF No Errors 
    BEGIN 
     UPDATE MainTable SET ProcessedStatus = 'Processed' WHERE ID = XXX 
     COMMIT TRANSACTION 
    ELSE 
     ROLLBACK TRANSACTION 

END 
+0

DJ,我要和你例子中看到的問題是,之前的漫長過程是跑了ProcessedBit設置爲true。如果長時間處理錯誤,那麼我留下的是ProcessedBit = true。謝謝你的幫助。 Keith – 2008-10-31 20:11:13

0

唯一的隔離級別,允許一個事務讀取由另一個事務正在進行中執行(其提交之前)的變化是:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
相關問題