请参阅以下代码:
Imports System.Transactions
Imports System.Data.SqlClient
Imports System.Web.Configuration
Partial Class _Default
Inherits System.Web.UI.Page
Private _ConString As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Dim objDR As SqlDataReader
_ConString = WebConfigurationManager.ConnectionStrings("TestConnection").ConnectionString
Dim objCon As New SqlConnection(_ConString)
Dim objCommand As New SqlCommand
objCommand.CommandText = "SELECT * FROM Person"
'Using scope As New TransactionScope()
objCon.Open()
Using scope As New TransactionScope()
objCommand.Connection = objCon
objDR = objCommand.ExecuteReader
Do While objDR.Read
Dim i As String = objDR("id2")
Dim objCommand2 As New SqlCommand
objCommand2.Connection = objCon
objCommand2.CommandText = "UPDATE Person SET URN=1 WHERE id2 = '" & i & "'"
objCommand2.ExecuteNonQuery() 'line 28
objCommand2.CommandText = "UPDATE Person SET URN=2 WHERE id2 = '" & i & "'"
objCommand2.ExecuteNonQuery() 'line 30
objCommand2.CommandText = "UPDATE Person SET URN=3 WHERE id2 = '" & i & "'"
objCommand2.ExecuteNonQuery() 'line 32
Loop
'scope.Complete() 'line 34
End Using
objDR.Close()
Catch ex As Exception
Throw
End Try
End Sub
End Class
即使scope.complete被注释掉,也会执行三个更新语句。我相信这是因为在TransactionScope外面打开了连接。
如果我想循环通过一百万人来发布这些更新,那么有两种选择:
1)完成所有更新并在最后将更改提交到数据库 2)在每个循环上提交更改 - 然后我将不得不为每个循环打开一个新连接。
开发人员总是选择选项1吗?即批量发布更新。
答案 0 :(得分:0)
您不应该立即提交所有更改。有了100万次更新,撤销日志将会非常庞大,您可能会遇到锁定问题,整个操作可能会花费不合理的时间。
批量发布更新是个好主意,只需记住将批量大小设置为合理的。例如,1000条记录。您可以并行运行更新 - 它应该更快。如果您可以将更新组织成逻辑部分,例如按部门划分的人员 - 请执行此操作,从长远来看,这将提高代码的可维护性。
另外,请考虑使用参数。
答案 1 :(得分:0)
从阅读文档看,事务范围看起来需要使用块(缺少)来包装连接。所以开放范围,开放连接,执行命令,提交范围。
http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
Connections,Commands,TransactionScope和Readers都实现了IDisposable并且需要一个using块(除非你反编译代码并验证IDisposable中的活动是无意义的,就像它们用于DataSet,DataTable和那个Bulk Insert的东西)
Neolisk说的一切。批量更新除非您有一个特殊情况,其中部分更新将是某种灾难。 (更有可能的是,一个大规模的交易将是另一种更糟糕的灾难 - 日志文件填满或者数据库引擎在消化大量交易的同时检查了很长时间的午餐)