6

私が次のことをした場合:

 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

すべてが期待どおりに機能します。並列バージョンが正しく動作しない理由を知っている人はいますか?

4

2 に答える 2

4

それがどのような技術なのかはわかりませんが、通常、トランザクションはスレッドにバインドされており、子スレッドには伝播しません。そうは言っても、各スレッドで新しいトランザクションを開始する必要があります。ただし、これは、スレッドと同じ数の独立したトランザクションがあることを意味します。

この制限は、トランザクションが単一スレッドの基礎となる SQL データベース接続に接続されているため、妥当です。

于 2011-11-18T19:33:41.977 に答える
4

次のように、トランザクションをワーカー スレッドに伝達できます。

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 の構文の問題はご容赦ください。これは私の母国語ではありません。

于 2011-11-24T00:29:44.330 に答える