3

我一直無法找到類似於我正在做的任何事情,並且由於預算問題,我不得不求助於您。我目前正在編寫一個導入應用程序,可以導入可變數量的記錄。這個可變數字很可能會非常高,可能達到數百萬。我們利用WCF流式傳輸將大塊數據發送到服務器進行處理。在服務器端,我們將數據轉儲到臨時SQL表中進行驗證。從那裏,使用TPL提取一定數量的記錄,然後將它們插入永久SQL存儲庫。還有更多的參與,但簡單來說就是它的大部分。目前唯一未解決的問題是我們允許用戶隨時取消導入。這意味着在保存這些記錄的過程中可能會發生取消操作。我們需要能夠回滾所有插入/更新的記錄。由於我們正在使用TPL處理記錄,所以我在分享交易時非常困難。我正在使用MSDN上列出的DependentTransaction方法(非常相似,http://msdn.microsoft.com/en-us/library/system.transactions.dependenttransaction(v=VS.100).aspx)。下面是一些代碼片段:是否可以使用DependentTransaction或多個DependentTransactions與TPL/Parallelism?

var currentTransaction = System.Transactions.Transaction.Current; 

...

// DataTable is simply a placeholder for X amount of records from the SQL temp table 
var partitions = Partitioner.Create(0, DataTable.Rows.Count, 100); 
Parallel.ForEach(partitions, (partition, state) => 
        { 
         using (var parallelTransaction = new TransactionScope(currentTransaction.DependentClone((DependentCloneOption.RollbackIfNotComplete))) 

這裏面TPL迭代中,也有很多選擇,插入和更新的發生。如果可能的話,我希望這些都在同一個事務下發生。或者至少可以通過TransactionScope進行管理,以便我們可以將所有內容都回滾。我不斷收到「事務上下文已被使用」的錯誤,然後幾乎立即中止。

我沒有正確使用DependentTransaction?我的要求甚至可能嗎?我知道事務通常是順序的,並不是在這種情況下使用的,但爲了簡單起見,爲了幫助我們實現一些瘋狂的功能來跟蹤插入的記錄並手動回滾,交易將是理想的!

有什麼建議嗎?

注:我已經嘗試使用本地狀態方法來並行迭代,但不管我做什麼,它都會產生相同的異常。另外,使用RollbackIfNotComplete或BlockCommitUntilComplete沒有影響。

+0

我已經看到了這個帖子(http://stackoverflow.com/questions/2186698/how-do-distributed-transactions-behave-with-multiple-connections-to-the-same-db-i)我想知道這是不可能的。這篇文章概述了我正在嘗試做的事情。有誰知道這是否改變了? –

+0

記錄被導入到臨時表中。在導入完成之前開始處理(驗證)臨時表?只有在導入完成後才能開始處理?如果他們取消,那麼刪除臨時表就很簡單。擁有數百萬條記錄的交易是一筆非常大的交易。在事務完成並且需要大事務日誌之前,您確實知道這將是未提交的數據? – Paparazzi

回答

0

管理SQL Server事務的最佳位置在T-SQL代碼中。由於您已經擁有了要在同一個SQL Server中插入/更新/刪除的所有數據,因此我沒有看到任何好的理由不僅僅是在T-SQL代碼中執行事務內的選擇/插入/更新。這是一個你可以使用的簡單模板。

-- REFERENCE: http://aleemkhan.wordpress.com/2006/07/21/t-sql-error-handling-pattern-for-nested-transactions-and-stored-procedures/ 
    -- ====================================================================================== 
    -- STANDARD HEADER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION 
    -- FOR SQL 2005 AND UP 
    -- ====================================================================================== 
    SET XACT_ABORT ON; 
    BEGIN TRY 
    DECLARE @TranStarted bit; SET @TranStarted = 0 
    IF(@@TRANCOUNT = 0) BEGIN BEGIN TRANSACTION; SET @TranStarted = 1; END ELSE SET @TranStarted = 0 
    -- ====================================================================================== 




    -- ================================================================== 
    -- ***** SQL CODE FOR SELECTS/INSERTS/UPDATES/DELETES GOES HERE ***** 
    -- ================================================================== 




    -- ====================================================================================== 
    -- STANDARD FOOTER FOR TRANSACTION LOGIC THAT WILL ALSO HANDLE BEING A NESTED TRANSACTION 
    -- FOR SQL 2005 AND UP 
    -- ====================================================================================== 
    IF(@TranStarted = 1 AND (XACT_STATE()) = 1) BEGIN SET @TranStarted = 0; COMMIT TRANSACTION; END 
    RETURN(0) 
    END TRY 
    BEGIN CATCH 
     DECLARE @ErrorMessage nvarchar(4000) 
      ,@ErrorNumber int 
      ,@ErrorSeverity int 
      ,@ErrorState int; 
     SELECT @ErrorMessage = ERROR_MESSAGE() + CHAR(13) + 'Actual Code Line that took the error: ' + CONVERT(nvarchar, ERROR_LINE()) 
               + CHAR(13) + 'Actual Proc that took the error: ' + CONVERT(nvarchar(126), ERROR_PROCEDURE()) 
      ,@ErrorSeverity = ERROR_SEVERITY() 
      ,@ErrorState = ERROR_STATE() 
      ,@ErrorNumber = ERROR_NUMBER(); 

    IF(@TranStarted = 1 AND (XACT_STATE()) = -1) BEGIN SET @TranStarted = 0; ROLLBACK TRANSACTION; END 
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState); 
    END CATCH 
    -- ====================================================================================== 
相關問題