Как распределенные транзакции ведут себя с несколькими подключениями к одной и той же БД в многопоточной среде?

Я пытаюсь определить поведение соединения нескольких баз данных в распределенной транзакции.

У меня есть длительный процесс, который порождает серию потоков, и каждый поток затем отвечает за управление своими подключениями к БД и тому подобное. Все это выполняется внутри области транзакции, и каждый поток зачисляется в транзакцию черезDependentTransaction объект.

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

Я хотел бы знать, как координатор транзакций обрабатывает запросы от нескольких подключений к одной и той же БД и целесообразно ли передавать объект подключения между потоками?

Я читал, что MS SQL допускает только одно соединение на транзакцию, но я ясно могу создать и инициализировать более одного соединения с одной и той же БД в одной транзакции. Я просто не могу выполнять потоки параллельно, не получая исключение «контекст транзакции используется другим сеансом» при открытии соединений. В результате соединения должны ждать выполнения, а не запускаться в одно и то же время, и в конце код выполняется до завершения, но нет никакой выгоды для многопоточности приложения из-за этой проблемы с блокировкой.

Код выглядит примерно так.

    Sub StartThreads()
        Using Scope As New TransactionScope
            Dim TL(100) As Tasks.Task
            Dim dTx As DependentTransaction
            For i As Int32 = 0 To 100
                Dim A(1) As Object
                dTx = CType(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete), DependentTransaction)
                'A(0) = some_other_data
                A(1) = dTx 'the Dependent Transaction

                TL(i) = Tasks.Task.Factory.StartNew(AddressOf Me.ProcessData, A) 'Start the thread and add it to the array
            Next

            Tasks.Task.WaitAll(TL) 'Wait for threads to finish

            Scope.Complete()
        End Using
    End Sub
    Dim TransLock As New Object
    Sub ProcessData(ByVal A As Object)
        Dim DTX As DependentTransaction = A(1)
        Dim Trans As Transactions.TransactionScope
        Dim I As Int32
        Do While True
            Try
                SyncLock (TransLock)
                    Trans = New Transactions.TransactionScope(DTX, TimeSpan.FromMinutes(1))
                End SyncLock
                Exit Do
            Catch ex As TransactionAbortedException
                If ex.ToString.Contains("Failure while attempting to promote transaction") Then
                ElseIf ex.Message = "The transaction has aborted." Then
                    Throw New Exception(ex.ToString)
                    Exit Sub
                End If
                I += 1
                If I > 5 Then
                    Throw New Exception(ex.ToString)
                End If
            Catch ex As Exception

            End Try
            Thread.Sleep(10)
        Loop
        Using Trans
            Using DALS As New DAC.DALScope
                Do While True
                    Try
                        SyncLock (TransLock)
                            'This opens two connection to the same DB for later use.
                            DALS.CurrentDAL.OpenConnection(DAC.DAL.ConnectionList.FirstConnection)
                            DALS.CurrentDAL.OpenConnection(DAC.DAL.ConnectionList.SecondConnection)
                        End SyncLock
                        Exit Do
                    Catch ex As Exception
                        'This is usually where I find the bottleneck
                        '"Transaction context in use by another session" is the exception that I get
                        Thread.Sleep(100)
                    End Try
                Loop

                '*****************
                'Do some work here
                '*****************

                Trans.Complete()
            End Using
        End Using
        DTX.Complete()
    End Sub

РЕДАКТИРОВАТЬ

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

Возможно, они изменят это поведение в будущем.

Ответы на вопрос(1)

Ваш ответ на вопрос