TransactionScope всегда пытается перейти на MSDTC - PullRequest
7 голосов
/ 05 мая 2011

Я пытаюсь использовать область транзакции внутри цикла. Весь цикл происходит с использованием одного подключения к базе данных. Я использую Entity Framework 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

Редактировать: вместо TransactionScope, если я использую connection.BeginTransaction (), транзакция.Commit () и транзакция.Rollback (), он работает нормально. Однако я все же хотел бы найти способ заставить TransactionScope работать.

Ответы [ 2 ]

1 голос
/ 11 мая 2011

Вы проверяли описание для EnlistTransaction в MSDN ?В нем говорится:

Новое в ADO.NET 2.0 - поддержка использования метода EnlistTransaction для зачисления в распределенную транзакцию.Поскольку он подключает соединение в экземпляре транзакции, EnlistTransaction использует функциональные возможности, доступные в пространстве имен System.Transactions для управления распределенными транзакциями.Как только соединение явно зачислено в транзакцию, оно не может быть исключено или зачислено в другую транзакцию, пока не завершится первая транзакция.

В нем упоминается только распределенная транзакция.Вы можете попробовать использовать connection.BeginTransaction вместо этого.Он вернет экземпляр EntityTransaction, и вы позвоните Commit для завершения транзакции.

1 голос
/ 11 мая 2011

TransactionScope Изначально возникла проблема, из-за которой она переводила транзакцию в распределенную транзакцию при обнаружении другого соединения, даже если все соединения были с одной и той же базой данных.Это была известная проблема во фреймворке.

Я полагаю, что они решали эту проблему в .NET 4, какую версию вы используете?

В этом ответе было предоставлено решение:

Почему TransactionScope использует распределенную транзакцию, когда я использую только LinqToSql и Ado.Net

По сути то же самое, что комментарий к вашему вопросу, предлагающий фактически использовать только один физическийсоединение из пула - поэтому зачисляется только одно соединение.

Повторное рассмотрение вашего вопроса. Я вижу, что приведенное выше вряд ли изменится, так как вы все равно используете только одно соединение.Возможно, попробуйте закрыть и повторно открыть соединение на каждой итерации явно и использовать преимущества пула соединений.

Или, что еще лучше, отмените использование TransactionScope, так как IDbTransaction имеет достаточно возможностей для покрытия вашегокод.

...