交易错误 - 我问得太多了吗?

时间:2016-03-21 18:01:38

标签: c# .net vb.net transactions ado.net

我在vb.net中运行以下循环,超过1000次的迭代会发出1000个更新命令:

Dim updateRoute As String = "UPDATE [Routes] SET [matching_route_id] = ? WHERE [ID] = ?"
Using transaction As OleDbTransaction = myconnection.BeginTransaction()
    Dim id As Integer
    For Each id In ids
        Using cmd2 As New OleDbCommand(updateRoute, myconnection)
            cmd2.Parameters.AddWithValue("?", id)
            cmd2.Parameters.AddWithValue("?", id)
            cmd2.ExecuteNonQuery()
        End Using
    Next
    transaction.Commit()
End Using

但我得到以下例外

  

ExecuteNonQuery需要命令才能拥有事务   分配给该命令的连接位于挂起的本地事务中。   该命令的Transaction属性尚未初始化。

这似乎告诉我,我需要在cmd2的每次迭代中开始一个事务。对我而言,这消除了使用交易的任何理由 - 因为我想这样做是一个大批量。即,事务应该在第一个UPDATE之前开始,并在最后一个UPDATE语句结束。

所以我想我的问题是双重的:

  1. 如何让vb.net在循环之前接受我的交易
  2. 或者,我如何运行这样的大批量更新。目前,一次更新一行几乎太慢了。

2 个答案:

答案 0 :(得分:4)

尝试将命令与事务关联,对于示例:

try

另一方面,如果Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction) cmd2.Parameters.AddWithValue("?", id) cmd2.Parameters.AddWithValue("?", id) cmd2.ExecuteNonQuery() End Using 使用RollBack块失败,您应该保证Commit示例:

Try/Catch

更新

我不确定但是如果你在数据库中遇到一个查询,它可以提高性能。或者,只需在每个Using transaction As OleDbTransaction = myconnection.BeginTransaction() Try Dim id As Integer For Each id In ids Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction) cmd2.Parameters.AddWithValue("?", id) cmd2.Parameters.AddWithValue("?", id) cmd2.ExecuteNonQuery() End Using Next transaction.Commit() Catch transaction.RollBack(); End Try End Using ID之间实现一个循环,并在每次单击中执行100更新,可以提高性能。

100

答案 1 :(得分:0)

尝试捕获的更好方法

      Using transaction As OleDbTransaction = myconnection.BeginTransaction()            
        Dim id As Integer
        Dim errors as Integer = 0

        For Each id In ids
            Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
                cmd2.Parameters.AddWithValue("?", id)
                cmd2.Parameters.AddWithValue("?", id)

                Try 
                  cmd2.ExecuteNonQuery()
                Catch
                  errors+=1
                End Try
            End Using
        Next

        If errors=0
          transaction.Commit()
        else
          transaction.RollBack();
        End If    
      End Using