TransactionScope - 每次迭代时提交

时间:2013-04-20 14:46:44

标签: vb.net

请参阅以下代码:

    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吗?即批量发布更新。

2 个答案:

答案 0 :(得分:0)

  1. 您不应该立即提交所有更改。有了100万次更新,撤销日志将会非常庞大​​,您可能会遇到锁定问题,整个操作可能会花费不合理的时间。

  2. 批量发布更新是个好主意,只需记住将批量大小设置为合理的。例如,1000条记录。您可以并行运行更新 - 它应该更快。如果您可以将更新组织成逻辑部分,例如按部门划分的人员 - 请执行此操作,从长远来看,这将提高代码的可维护性。

  3. 另外,请考虑使用参数。

答案 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说的一切。批量更新除非您有一个特殊情况,其中部分更新将是某种灾难。 (更有可能的是,一个大规模的交易将是另一种更糟糕的灾难 - 日志文件填满或者数据库引擎在消化大量交易的同时检查了很长时间的午餐)