TransactionScope не работает с параллельными расширениями? - PullRequest
6 голосов
/ 18 ноября 2011

Если я сделаю следующее:

 Using scope = New TransactionScope()
        entries.Content.ReadAs(Of IList(Of WebMaint)).AsParallel.ForAll(Sub(entry)
                                                                            _repos.Update(entry)
                                                                        End Sub)
        scope.Complete()
    End Using

TransactionScope не работает. Если я поставлю точку останова на scope.complete, никакая транзакция не будет активной, и обновления уже завершены.

Если я поменяю его на:

Using scope = New TransactionScope()
            entries.Content.ReadAs(Of IList(Of WebMaint)).ToList().ForEach(Sub(entry)
                                                                               _repos.Update(entry)
                                                                           End Sub)
            scope.Complete()
End Using

Все работает как положено. Кто-нибудь знает, почему параллельная версия не работает правильно?

Ответы [ 2 ]

4 голосов
/ 24 ноября 2011

Вы можете распространить транзакцию на рабочие потоки следующим образом:

Using scope = New TransactionScope()
    Dim rootTransaction As Transaction  = Transaction.Current

    entries.Content.ReadAs(Of IList(Of WebMaint)).AsParallel.ForAll(
        Sub(entry)    
            Dim dependentTransaction As DependentTransaction = rootTransaction.DependentClone(DependentCloneOption.RollbackIfNotComplete)

            _repos.Update(entry)

            dependentTransaction.Complete()
        End Sub)        

    scope.Complete()
End Using

ПРИМЕЧАНИЕ: прошу прощения за любые проблемы с синтаксисом VB, 'это не мой родной язык

4 голосов
/ 18 ноября 2011

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

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

...