2011-05-05 42 views
7

我想在循環內使用事務作用域。整個循環使用到數據庫的單個連接進行。我正在使用實體框架4進行數據庫訪問。在循環的第二次迭代期間,當執行LINQ to Entites查詢時,會拋出一個異常,指出服務器上的MSDTC不可用。TransactionScope總是嘗試升級到MSDTC

我讀過,明確打開連接,然後爭取交易應該解決這個問題,但它沒有。以下是反映正在發生的基本操作的示例代碼。

有關如何防止升級到MSDTC的任何想法?

Using context = New MyEntities() 
    Dim connection = context.Connection 

    connection.Open() 

    For index = 0 to (Me.files.Count - 1) 
     Dim query = From d In context.Documents 
        Where (d.DocumentID = documentID) 
        Select d.Status 

     Dim status = query.FirstOrDefault() 

     Using trans = New TransactionScope() 
      connection.EnlistTransaction(Transaction.Current) 

      Dim result = context.UpdateStatus(True) 

      If (result = 1) Then 
       WriteToFile() 
       trans.Complete() 
      End If 
     End Using 
    Next 
End Using 

編輯:相反的TransactionScope的,如果我用connection.BeginTransaction(),器transaction.commit(),和transaction.Rollback(),它工作正常。但是,我仍然想找到一種使TransactionScope工作的方法。

+0

這個論壇發貼幫助? http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/c3fd7555-7fff-44b8-8e1e-030073c20597/它看起來像建議啓動事務,然後打開連接,然後運行您的查詢。 – mkedobbs 2011-05-05 16:19:52

+0

想法是打開連接,然後使用一個連接運行所有查詢 - 出於性能原因。 – NYSystemsAnalyst 2011-05-05 16:22:33

+0

如果使用連接池,則沒有性能原因。 – 2011-05-05 20:42:09

回答

1

TransactionScope最初有一個問題,即當所有連接都在同一個數據庫中時,它會將事務提升爲分佈式事務。這是該框架中的一個已知問題。

我相信他們在.NET 4中解決了這個問題,您使用的是哪個版本?

一種解決方法已經在這個答案提供了:

Why is TransactionScope using a distributed transaction when I am only using LinqToSql and Ado.Net

基本上相同,你的問題建議實際只使用從池中的一個物理連接的評論 - 所以只有一個連接被徵召。

再次審查您的問題我可以看到上面不會有所不同,因爲您只使用一個連接。也許嘗試明確地在每次迭代中關閉並重新打開連接,並使用連接池的好處。

或者更理想的情況是,放棄使用TransactionScope作爲IDbTransaction有足夠的範圍來覆蓋您的代碼。

+0

一旦你使用多於一個連接,事務必須被提升爲分佈式 - 如果它們連接到同一個數據庫,它們沒有區別。當沒有涉及其他事務資源時,本地事務僅在單個連接上處理。 – 2011-05-11 08:06:55

+0

這個論壇問題的答案表明這是一個限制,並將解決:http://social.msdn.microsoft.com/forums/en-US/adodotnetdataproviders/thread/3ce488eb-55a8-4535-adc7-c5b29a1523b5/ – 2011-05-11 08:09:22

+0

然而,他們與OP的情況不盡相同。我似乎比較的情況是,當一個事務範圍有多個連接時,而OP似乎有一個連接和多個事務範圍......之前沒有看到過。 – 2011-05-11 08:11:43

1

您是否在MSDN中查看描述爲EnlistTransaction?它說:

新的ADO.NET 2.0是使用EnlistTransaction方法進行 登記在分佈式事務 支持。 因爲它在 事務實例中登記連接,所以EnlistTransaction利用 功能 System.Transactions命名空間中的 管理分佈式事務。 一旦連接明確地登記在一個交易中 ,它就不能登記或登記在另一個 交易中,直到第一個 交易結束。

它只提到分佈式事務。您可以嘗試使用connection.BeginTransaction。它將返回實例EntityTransaction,您將致電Commit完成交易。