C# 交易错误-我要求太多了吗?
我在vb.net中运行以下循环,其中超过1000次迭代发出1000次更新命令: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
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
的每次迭代中开始一个事务。对我来说,这就打消了使用事务的任何理由——因为我想把它作为一个大批量来做。即,事务应在第一次更新之前开始,并在最后一次更新语句结束
所以我想我的问题有两个:
尝试将命令与事务关联,例如:
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循环放入中?这样,它只创建一次,但每次循环迭代时都会设置它的事务。如果这样做,则必须清除参数并替换为新值。我想你可以点击一下数据库,但我不确定你是否能表现得很好。我会更新的。