4

我有以下例程:

For j = 1 To NumItems
    dbValueLookup.Load(j)
    Using scope As New TransactionScope()
        For i = firstIndex To lastIndex

            'dbValueLookup is basically just a Dictionary of items already in the DB
            If dbValueLookup.ContainsKey(i) Then
                'updateData is a subroutine that updates this row with new data
                updateData(j,i)
                rowsUpdated = rowsUpdated + 1
                dbValueLookup.Remove(i)
            Else
                'updateData is a subroutine that adds a new row to DB
                addData(j,i)
                rowsAdded = rowsAdded + 1
            End If
        Next

        If dbValueLookup.Count = 0 Then
            'This commits the transaction - records will be updated when End Using is reached
            scope.Complete()
            If rowsAdded + rowsUpdated > 0 Then
                ShowMessage("Records Updated: " + rowsUpdated.ToString() + " Records Added: " + rowsAdded.ToString())
            End If

        Else
            'We are left with data from the database that was not updated.  This is a problem, so we don't "Complete" the scope.
            'This will result in a rollback.
            ShowWarningMessage("Incomplete Data for " + i.ToString())
        End If
    End Using
Next

偶尔对我们的生产和测试 Oracle 11g 数据库运行它(或者如果有模式,我还没有找到它)会生成 Oracle 错误:ORA-02049:超时:分布式事务等待锁定

由于这是针对测试数据库运行的唯一进程,因此不同用户竞争锁定应该没有任何问题。

任何想法可能导致此错误?

提前致谢。

4

1 回答 1

0

所以听起来你必须有两个事务竞争行锁。

只是在这里头脑风暴,但是如果dbValueLookup.Count = 0,那么你会打电话addData(这听起来像是一个INSERT?),但你不会打电话scope.Complete()来提交你的交易。

我不确定是否End Using会始终提交交易。

你真的需要TransactionScope在循环的每次迭代中创建吗?为什么不创建一个事务,完成所有更新/插入,然后提交一次?

于 2011-06-26T00:09:30.643 回答