台灣最大程式設計社群網站
線上人數
1113
 
會員總數:245232
討論主題:189102
歡迎您免費加入會員
討論區列表 >> 專欄文章 >> 確保交易的新利器(TransactionScope)初體驗-Part 1
[]  
[我要回覆]
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
確保交易的新利器(TransactionScope)初體驗-Part 1
價值 : 0 QP  點閱數:684 回應數:0

樓主

topcat 版主
高級顧問
102939 162
31976 12305
發送站內信

捐贈 VP 給 topcat
從.NET Framework 2.0以後,有個新的東西稱之為TransactionScope,他可以讓我們在處理交易的時候,可以確保交易的完整性,並且使用十分的簡便,小喵在此測試一下他的撰寫方式與結果,在測試過程中,驚人的發現了MSDN範例的一個錯誤內容。

小喵以北風資料庫當作小喵測試的資料。就選用Employee這個資料表來測試看看,我們先看一下資料表的Layout以及他本來資料的狀況

資料表Layout

原本資料狀況

小喵會寫兩段更改資料的語法,分別

1.將EmployeeID=1的LastName最後一個字加上【X】字元,這部分是應該可以過得
2.小喵試著要把EmployeeID=9的FirstName設定為【ABC123456789】,從資料表Layout看出,FirstName欄位大小是10個字元,因此這個應該會出現錯誤
理想的狀況應該是,他會Rollback,讓1.的變化也回覆

首先,要看一下TransactionScope的說明請參考以下鏈結

http://msdn.microsoft.com/zh-tw/library/system.transactions.transactionscope(VS.80).aspx

接著就是測試的程式碼:

小喵把北風加入asp.net的專案中,在畫面上安排一個Button1,並且從伺服器總館中把Empolyee這個資料表拉到設計中,系統會自動產生Employee這個資料表的GridView與SqlDataSouce以及在Web.Config中,會把ConnectionString準備好。接著小喵雙擊Button1開始寫Button1的程式碼

一開始,當然要Imports相關的NameSpace,在撰寫時,發現彈不出System.Transactions,於是小喵先把System.Transactions加入參考。然後在最上方加入Imports


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
搜尋相關Tags的文章: [ Transaction ] , [ ASP.NET ] , [ ADO.NET ] , [ Scope ] ,
本篇文章發表於2008-05-16 11:38
== 簽名檔 ==
====== 以下是簽名檔(不是回應內容) ======
世界上有兩種東西,分享給別人後,不但不會變少,反而變更多
一個是快樂,另一個是知識
而分享知識,不但獲得更多知識,更獲得快樂~

知識,從分享開始....

歡迎到小喵的Blog:
Topcat姍舞之間的極度凝聚
https://dotblogs.com.tw/topcat/
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
目前尚無任何回覆
   

回覆
如要回應,請先登入.