C# 交易错误-我要求太多了吗?

C# 交易错误-我要求太多了吗?,c#,.net,vb.net,transactions,ado.net,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

我在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
但我得到了以下例外

ExecuteOnQuery要求命令在 分配给该命令的连接位于挂起的本地事务中。 命令的事务属性尚未初始化

这似乎告诉我,我需要在
cmd2
的每次迭代中开始一个事务。对我来说,这就打消了使用事务的任何理由——因为我想把它作为一个大批量来做。即,事务应在第一次更新之前开始,并在最后一次更新语句结束

所以我想我的问题有两个:

  • 如何让vb.net在循环之前接受我的事务
  • 或者,如何运行这样的大批量更新。目前,一次更新一行的速度太慢,令人望而却步
    尝试将命令与事务关联,例如:

    Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.ExecuteNonQuery()
    End Using
    
    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
    
    另一方面,如果使用
    Try/Catch
    块的
    Commit
    失败,您应该保证
    回滚,例如:

    Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.ExecuteNonQuery()
    End Using
    
    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
    
    更新 我不确定,但如果您在数据库上输入一个查询,它可能会提高性能。或者,只需在每个
    100
    id之间实现一个循环,每次点击一次执行
    100
    更新,就可以提高性能

    Using transaction As OleDbTransaction = myconnection.BeginTransaction()
        Try     
            Dim id As Integer
            Dim b As New StringBuilder()
    
            For Each id In ids
                b.AppendFormat("UPDATE [Routes] SET [matching_route_id] = {0} WHERE [ID] = {0}; ", id)
            Next
    
            Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)              
                cmd2.ExecuteNonQuery()
            End Using
            transaction.Commit()
        Catch
            transaction.RollBack();
        End Try     
    End Using
    

    尝试将命令与事务关联,例如:

    Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.ExecuteNonQuery()
    End Using
    
    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
    
    另一方面,如果使用
    Try/Catch
    块的
    Commit
    失败,您应该保证
    回滚,例如:

    Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.Parameters.AddWithValue("?", id)
        cmd2.ExecuteNonQuery()
    End Using
    
    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
    
    更新 我不确定,但如果您在数据库上输入一个查询,它可能会提高性能。或者,只需在每个
    100
    id之间实现一个循环,每次点击一次执行
    100
    更新,就可以提高性能

    Using transaction As OleDbTransaction = myconnection.BeginTransaction()
        Try     
            Dim id As Integer
            Dim b As New StringBuilder()
    
            For Each id In ids
                b.AppendFormat("UPDATE [Routes] SET [matching_route_id] = {0} WHERE [ID] = {0}; ", id)
            Next
    
            Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)              
                cmd2.ExecuteNonQuery()
            End Using
            transaction.Commit()
        Catch
            transaction.RollBack();
        End Try     
    End Using
    

    一种更好的试捕方法

          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
    

    一种更好的试捕方法

          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
    

    您不需要每次迭代都使用新命令,只需要使用新参数值您不需要每次迭代都使用新命令,只需要使用新参数值即可!这是可行的,但过程仍然非常缓慢。有没有更好的方法来进行大规模更新?也许您可以通过存储过程获得一些改进,然后从ado.net调用它。我从未尝试过使用ado.net中的批处理更新,但请看一看。是否可以创建一次
    cmd2
    变量,然后使用cmd2…
    语句将for循环放入
    中?这样,它只创建一次,但每次循环迭代时都会设置它的事务。如果这样做,则必须清除参数并替换为新值。我想你可以点击一下数据库,但我不确定你是否能表现得很好。我会更新的,很好!这是可行的,但过程仍然非常缓慢。有没有更好的方法来进行大规模更新?也许您可以通过存储过程获得一些改进,然后从ado.net调用它。我从未尝试过使用ado.net中的批处理更新,但请看一看。是否可以创建一次
    cmd2
    变量,然后使用cmd2…
    语句将for循环放入
    中?这样,它只创建一次,但每次循环迭代时都会设置它的事务。如果这样做,则必须清除参数并替换为新值。我想你可以点击一下数据库,但我不确定你是否能表现得很好。我会更新的。