Imports System
Imports System.Transactions
Imports System.Data
Imports System.Data.SqlClient
接著就撰寫Button1 Click事件的內容,小喵依照MSDN上面的範例,撰寫以下的內容
Using Scope As New TransactionScope
Try
Dim ConnStr As String = ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString1").ConnectionString
Using Conn As New SqlConnection(ConnStr)
Conn.Open()
Dim SqlTxt As String = ""
Dim Cmmd As SqlCommand
SqlTxt += " Update Employees "
SqlTxt += " Set LastName = LastName + 'X' "
SqlTxt += " Where EmployeeID = @EmployeeID "
SqlTxt += " "
Cmmd = New SqlCommand(SqlTxt, Conn)
Cmmd.Parameters.AddWithValue("@EmployeeID", 1)
Cmmd.ExecuteNonQuery()
'---以上這一段理論上是可以正常通過的
'---以下這段因為超過欄位大小,應該會有Exception
SqlTxt = ""
SqlTxt += " Update Employees "
SqlTxt += " Set FirstName = 'ABC1234567890' "
SqlTxt += " Where EmployeeID = @EmployeeID "
SqlTxt += " "
Cmmd = New SqlCommand(SqlTxt, Conn)
Cmmd.Parameters.AddWithValue("@EmployeeID", 9)
Cmmd.ExecuteNonQuery()
End Using
Catch ex As Exception
Response.Write(ex.Message.ToString)
End Try
' The Complete method commits the transaction. If an exception has been thrown,
' Complete is called and the transaction is rolled back.
'設定交易完成
Scope.Complete()
End Using
Me.GridView1.DataBind()
結果太令人意外了,竟然沒有把這兩段維護包在一個Transaction中,小喵從以往的經驗裡面,判斷,Scope.Complete()應該要在沒有Exception的狀況,才進行。很顯然的,他的位置不對,因此小喵覺得他的範例中註解的那句話不正確。小喵試著把他的位置調整一下,調整後如下:
Using Scope As New TransactionScope
Try
Dim ConnStr As String = ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString1").ConnectionString
Using Conn As New SqlConnection(ConnStr)
Conn.Open()
Dim SqlTxt As String = ""
Dim Cmmd As SqlCommand
SqlTxt += " Update Employees "
SqlTxt += " Set LastName = LastName + 'X' "
SqlTxt += " Where EmployeeID = @EmployeeID "
SqlTxt += " "
Cmmd = New SqlCommand(SqlTxt, Conn)
Cmmd.Parameters.AddWithValue("@EmployeeID", 1)
Cmmd.ExecuteNonQuery()
'---以上這一段理論上是可以正常通過的
'---以下這段因為超過欄位大小,應該會有Exception
SqlTxt = ""
SqlTxt += " Update Employees "
SqlTxt += " Set FirstName = 'ABC1234567890' "
SqlTxt += " Where EmployeeID = @EmployeeID "
SqlTxt += " "
Cmmd = New SqlCommand(SqlTxt, Conn)
Cmmd.Parameters.AddWithValue("@EmployeeID", 9)
Cmmd.ExecuteNonQuery()
End Using
'正確的位置應該在這裡,也就是當有意外狀況的時候,應該要不能Scope.Complete()
'設定交易完成
Scope.Complete()
Catch ex As Exception
Response.Write(ex.Message.ToString)
End Try
End Using
Me.GridView1.DataBind()
經過這樣位置調整後,終於有了預期的效果,當第二個維護發生狀況時,同時把第一個維護的結果Rollback了。因此請大家要使用TransactionScope的時候,要特別注要安排Scope.Complete的位置要正確,才能達到預期的效果。
結論:
使用TransactionScope用法相當簡單,只要宣告Scope,並把要維護的過程包起來,就能夠確保維護過程的交易(Transaction)完整性。不過使用時要特別特別注意Scope.Complete放的位置,要在確定沒有Exception的狀況下,才使用Scope.Complete來讓Transaction進行Commit。
另外,TransactionScope不只是這樣而已,使用物件導向設計,在一個商業邏輯中用了數個物件維護資料,也可透過TransactionScope來確保交易的完整性,請看下一篇文章【確保交易的新利器(TransactionScope)初體驗-Part 2(物件維護的交易確保)】
本文同步發表於小喵的Blog
http://www.dotblogs.com.tw/topcat