请参阅以下代码:
Private Sub TransactionExample3()
Dim objDR As SqlDataReader
Dim objCommand As SqlCommand, objCommand2 As SqlCommand
Dim objCon As SqlConnection
Dim objCon2 As SqlConnection
Dim id As Integer
Dim list As List(Of Integer) = New List(Of Integer)
Try
_ConString = "Data Source=databaseserver;Initial Catalog=Person;User ID=username;Password=password;MultipleActiveResultSets=True"
list.Add(1)
list.Add(2)
list.Add(3)
For Each i As Integer In list
Using trans = New TransactionScope()
objCon2 = New SqlConnection(_ConString)
objCon2.Open()
objCommand2 = New SqlCommand()
objCommand2.Connection = objCon2
Using objCon2
objCommand2.CommandText = "UPDATE Person SET forenames = @forenames WHERE " & _
" Reference = @Reference "
objCommand2.Parameters.AddWithValue("@forenames", i + 1)
objCommand2.Parameters.AddWithValue("@Reference", i)
objCommand2.ExecuteNonQuery()
objCommand2.Parameters.Clear()
End Using
trans.Complete()
End Using
Next
Catch ex As Exception
Throw
Finally
End Try
End Sub
此代码适用于每个循环,更改将提交到数据库。
现在请看下面的代码:
Private Sub TransactionExample3()
Dim objDR As SqlDataReader
Dim objCommand As SqlCommand, objCommand2 As SqlCommand
Dim objCon As SqlConnection
Dim objCon2 As SqlConnection
Dim id As Integer
Try
_ConString = "Data Source=server;Initial Catalog=Person;User ID=Username;Password=Password;MultipleActiveResultSets=True"
objCon = New SqlConnection(_ConString)
objCommand = New SqlCommand("SELECT top 10 * from Person")
objCommand.Connection = objCon
objCon.Open()
objDR = objCommand.ExecuteReader()
Do While objDR.Read
objCon2 = New SqlConnection(_ConString)
objCon2.Open()
Using trans = New TransactionScope()
objCommand2 = New SqlCommand()
objCommand2.Connection = objCon
Using objCon2
objCommand2.CommandText = "UPDATE Person SET forenames = @forenames WHERE " & _
" Reference = @Reference "
objCommand2.Parameters.AddWithValue("@forenames", objDR("Reference") + 10)
objCommand2.Parameters.AddWithValue("@Reference", objDR("Reference"))
objCommand2.ExecuteNonQuery()
objCommand2.Parameters.Clear()
End Using
End Using
Loop
objDR.Close() 'line 16
Catch ex As Exception
Throw
Finally
End Try
End Sub
在第二个代码exherpt中,范围不完整(scope.complete),但结果仍然在while循环的每次迭代时提交给数据库。这是为什么?
答案 0 :(得分:2)
在第一个循环中,TransactionScope的打开位于连接打开之前。在第二个是后。该连接未在事务中登记,因此每个命令都在不由事务持有的情况下执行。
尝试切换这些行
Do While objDR.Read
Using trans = New TransactionScope()
objCon2 = New SqlConnection(_ConString)
objCon2.Open()
.....
现在您需要调用trans.Complete()
Private Sub TransactionExample3()
Dim objDR As SqlDataReader
Dim objCommand As SqlCommand, objCommand2 As SqlCommand
Dim objCon As SqlConnection
Dim objCon2 As SqlConnection
Dim id As Integer
_ConString = "Data Source=server;Initial Catalog=Person;User ID=Username;Password=Password;MultipleActiveResultSets=True"
Using objCon = New SqlConnection(_ConString)
objCommand = New SqlCommand("SELECT top 10 * from Person")
objCommand.Connection = objCon
objCon.Open()
objDR = objCommand.ExecuteReader()
Using trans = New TransactionScope()
Using objCon2 = New SqlConnection(_ConString)
objCon2.Open()
Do While objDR.Read
objCommand2 = New SqlCommand()
objCommand2.Connection = objCon
Using objCon2
objCommand2.CommandText = "UPDATE Person SET forenames = @forenames WHERE " & _
" Reference = @Reference "
objCommand2.Parameters.AddWithValue("@forenames", objDR("Reference") + 10)
objCommand2.Parameters.AddWithValue("@Reference", objDR("Reference"))
objCommand2.ExecuteNonQuery()
objCommand2.Parameters.Clear()
End Using
Loop
objDR.Close() 'line 16
End Using
trans.Complete()
End Using
End Using
End Sub
我建议在循环之外移动事务和连接开头并调用Complete并在foreach循环之后销毁连接,如果我正确理解你的代码你在每个循环更新一条记录,那么只有你的事务才有意义想要更新所有记录或没有。另一个小的优化可能是在循环外移动SqlCommand和Parameters的创建。您只更新循环内的参数值,而不会在每个循环中销毁和重建参数集合