交易错误——我是不是要求太多了?
Transaction Errors - Am I asking too much?
我 运行 在 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 requires the command to have a transaction when the
connection assigned to the command is in a pending local transaction.
The Transaction property of the command has not been initialized.
这似乎告诉我,我需要在 cmd2
的每次迭代开始时开始交易。对我来说,这消除了使用交易的任何理由——因为我想作为一个大批量来做。即,事务应在第一个 UPDATE 之前开始并在最后一个 UPDATE 语句结束。
所以我想我的问题有两个方面:
- 如何让 vb.net 在循环前接受我的交易
- 或者,我如何 运行 像这样进行大批量更新。目前,一次更新一行几乎太慢了。
尝试将命令关联到事务,例如:
Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
cmd2.Parameters.AddWithValue("?", id)
cmd2.Parameters.AddWithValue("?", id)
cmd2.ExecuteNonQuery()
End Using
另一方面,如果 Commit
使用 Try/Catch
块失败,您应该保证 RollBack
,例如:
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
更好的 try catch 方法
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
我 运行 在 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 requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
这似乎告诉我,我需要在 cmd2
的每次迭代开始时开始交易。对我来说,这消除了使用交易的任何理由——因为我想作为一个大批量来做。即,事务应在第一个 UPDATE 之前开始并在最后一个 UPDATE 语句结束。
所以我想我的问题有两个方面:
- 如何让 vb.net 在循环前接受我的交易
- 或者,我如何 运行 像这样进行大批量更新。目前,一次更新一行几乎太慢了。
尝试将命令关联到事务,例如:
Using cmd2 As New OleDbCommand(updateRoute, myconnection, transaction)
cmd2.Parameters.AddWithValue("?", id)
cmd2.Parameters.AddWithValue("?", id)
cmd2.ExecuteNonQuery()
End Using
另一方面,如果 Commit
使用 Try/Catch
块失败,您应该保证 RollBack
,例如:
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
更好的 try catch 方法
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