TransactionScope总是尝试升级到MSDTC

时间:2011-05-05 14:30:49

标签: .net entity-framework transactions transactionscope

我试图在循环中使用事务范围。整个循环使用与数据库的单个连接进行。我正在使用实体框架4进行数据库访问。在循环的第二次迭代期间,当执行LINQ to Entites查询时,将抛出异常,指出服务器上的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

编辑:如果我使用connection.BeginTransaction(),transaction.Commit()和transaction.Rollback(),而不是TransactionScope,它可以正常工作。但是,我仍然希望找到一种使TransactionScope工作的方法。

2 个答案:

答案 0 :(得分:1)

TransactionScope最初有一个问题,即当所有连接都在同一个数据库中时,它会在遇到另一个连接时将事务提升到分布式事务。这是框架中的一个已知问题。

我相信他们在.NET 4中解决了这个问题,您使用的是什么版本?

此答案中提供了一种解决方法:

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

基本上与您的问题的评论相同,建议实际上只使用池中的一个物理连接 - 因此只有一个连接被登记。

再次回顾你的问题我可以看到上面的内容不会有所不同,因为你只使用一个连接。也许尝试明确地关闭并重新打开每次迭代的连接,并使用连接池的好处。

或者更理想的是,放弃TransactionScope的使用,因为IDbTransaction有足够的范围来覆盖您的代码。

答案 1 :(得分:1)

您是否在MSDN中查看了EnlistTransaction的说明?它说:

  

ADO.NET 2.0中的新功能支持   使用EnlistTransaction方法   登记分布式交易。   因为它在一个连接中   交易实例,   EnlistTransaction利用了   功能可用   System.Transactions命名空间   管理分布式事务。   一旦明确连接   在一项交易中入伍,它不能   在另一个人中没有入伍或入伍   交易直到第一次   交易结束。

它只提到分布式交易。您可以尝试使用connection.BeginTransaction代替。它将返回EntityTransaction的实例,您将调用Commit来完成交易。