我试图在循环内使用事务作用域。整个循环是通过与数据库的单个连接进行的。我正在使用 Entity Framework 4进行数据库访问。在循环的第二次迭代过程中,当执行LINQ to Entites查询时,将引发异常,指出服务器上的MSDTC不可用。

我已经读过,显式打开连接然后加入事务可以解决此问题,但事实并非如此。下面的示例代码反射(reflect)了正在发生的基本操作。

关于如何防止升级到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工作的方法。

最佳答案

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

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

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

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

基本上与您对问题的评论相同,该评论暗示实际上仅使用池中的一个物理连接-因此仅征用了一个连接。

再次查看您的问题,我可以看到上面的内容可能并没有什么不同,因为无论如何您只使用一个连接。也许尝试在每次迭代中显式关闭和重新打开连接,然后利用连接池的好处。

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

关于.net - TransactionScope始终尝试升级为MSDTC,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5899430/

10-13 06:56