2013-10-08 16 views
1

我正嘗試使用實體框架運行以下事務。在事務範圍內,我從DB調用存儲過程。使用實體框架在事務內部調用存儲過程

using (mother_Entities entitiesContext = context.Value) 
{ 
    using (var transactionScope = new TransactionScope()) 
    { 
     // a lot of create, insert, update operations goes here 
     ... 
     entitiesContext.SaveChanges(); 

     //Execute stored procedure: 
     var paramMessage = new ObjectParameter("MESSAGE", ""); 
     var paramMotherid = new ObjectParameter("MOTHERID", motherProductId); 
     var paramTochteridlist = new ObjectParameter("TOCHTER_ID_LIST", string.Join(";", motherIds)); 
     var paramError = new ObjectParameter("ERROR", typeof(int)); 
     var paramErrorText = new ObjectParameter("ERR_TEXT", typeof(string)); 

     entitiesContext.ExecuteFunction("SP_DOCUWARE_UPDATE", paramMessage, paramMotherid, 
              paramTochteridlist, paramError, paramErrorText); 

     ... 
     transactionScope.Complete(); 
    } 
} 

上線entitiesContext.ExecuteFunction()我得到異常Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0

我的存儲過程不使用任何交易,不調用任何其他函數或過程。所以我不明白爲什麼我不能在事務內執行事務過程。

UPDATE:

哦,我發現這個存儲過程:

... 
    IF @COMMIT = 1 
    BEGIN 
     IF @CANCEL = 1 
      ROLLBACK 
     ELSE 
      COMMIT 
    END 
    ELSE IF @CHECK = 1 
     ROLLBACK 
    END 
... 

可能被提交後會拋出異常。但如何逃避這個錯誤?

+0

我認爲這不是用TransactionScope,而是用Stored proc。請檢查存儲過程是否與您在呼叫之前傳遞/設置的參數一起工作。 –

+0

你的意思是說「正在使用參數」?我更新了我的問題。 – algreat

+0

我的意思是,具有相同值的profiler trace具有相同的值,能夠在SQL server Management Studio中運行異常... –

回答

3

我解決了我的問題。

在存儲過程中有一個ROLLBACKCOMMIT關鍵字。但在程序中的任何地方都沒有BEGIN TRANSACTION。從一開始,我認爲這很奇怪。

正如你所知道COMMIT遞減@@TRANCOUNT由1或者更精確地說:

如果@@ TRANCOUNT爲1,COMMIT TRANSACTION使所有數據修改 因爲事務的永久部分開始執行 數據庫釋放交易持有的資源,並將 @@ TRANCOUNT減爲0.如果@@ TRANCOUNT大於1,則COMMIT TRANSACTION 僅將@@ TRANCOUNT遞減1,並且事務處於活動狀態。

在我的情況下,我開始在代碼中的交易。並且該程序中的COMMIT正在嘗試提交我的交易並減少@@TRANCOUNT,但尚未完成。

因此,我將BEGIN TRANSACTION添加到存儲過程,它工作正常。

0

在提交內部事務(完成)之前,您不能提交外部事務(SaveChanges)。我懷疑SaveChanges的內部調用內部交易也是如此。 (未驗證)

+1

使用事務範圍時,SaveChanges不會提交任何更改。你必須使用transactionScope.Complete(); – algreat

+0

它是預期的行爲。你在內部交易範圍之外做什麼?你真的需要它嗎?我相信在隱式的'DbContext'事務範圍內使用'ExecuteFunction'會在同一個事務中執行它,這看起來像你想要的。無論如何,你還應該看看你的後端限制,例如SQL Server並不真正支持嵌套事務(它只是[將所有事務展平到外部事務](http://technet.microsoft.com/en-us/library /ms189336.aspx)),這解釋了行爲。那麼是的,刪除顯式交易範圍有幫助嗎? – tne

相關問題