您的位置:首页 > 其它

新世代交易管理機制~System.Transactions

2008-06-24 18:55 225 查看
新世代交易管理機制~System.Transactions

Transaction交易處理在嚴謹度較高的應用程式必備的基本功能,傳統.NET處理交易有兩種途徑,一是使用ADO.NET為主的SqlTransaction,另一就是透過Enterprise Services(COM+)來達成,那新世代的交易機制還提供了另一種更優的選擇,就是System.Transaction。

--------------------------------------------------------------------------------

【本文內容及程式碼引用聖殿祭司ASP.NET 3.5新書】

在一開始撰寫【新世代交易管理機制~System.Transactions】這章時,我足足焦慮心煩了三天,因為不知道該如何下筆談這章,不是程式面的問題,而是"脈絡",如果我無法告訴讀者說System.Transaction交易管理機制創造的由來,還有使用它的目的,即使貼了一堆實作的程式碼,我個人也會認為是沒用的知識,是失敗的作品,程式不怕不會寫,因為可抄可參考的太多了,但可怕的是,無法辨證程式運用場合是否正確?是否為合理的運用?擺了一堆莫名奇妙的Code在自己的專案中,自已又說不出的所以然,我想這才是為日後問題發生時,埋下一個致命因素,好再我看了很多國外專家的文章,了解System.Transaction創造的起源,再加上我自己的研究心得,最後這星期終於完成了System.Transactions的寫作主題,以下開始是介紹。

傳統.NET1.x的交易程式機制有兩種:

(1)ADO.NET明確交易,指SqlTransaction。

(2)Enterprise Services的宣告式交易兩種。

然而本章所要談的主角不是以上兩者,而是System.Transactions新世代的交易管理機制,System.Transactions是一個命名空間,而裡面包含許多和交易有關的類別,但要說明為什麼要發明System.Transactions這個東西之前,就要先解釋傳統(1)ADO.NET明確交易(2)Enterprise Services的宣告式交易的缺點及侷限性:

(1)ADO.NET明確交易

ADO.NET明確交易效能最快,吃系統資源最少,但是功能過份簡單,只能管理單一物件和單一持久資源間的交易,也就是它只能應付單一SqlConnection對單一SQL Server之間的交易管理(或是Oracle),而無法應付多個SqlConnection對多個SQL Server間的分散式交易。

(2)Enterprise Services的宣告式交易

Enterprise Services的宣告式交易透過COM+型式來提供交易服務,並且需要用到MSDTC(Microsoft Distributed Transaction Coordinator)來協調分散式交易,交易功能最為強大,但是會付出較為昂貴的成本代價,而交易執行的速度最慢。

註:

MSDTC之所以較慢與使用成本較大有兩個主要原因:

1. 因為MSDTC與你的應用程式分處於不同的Process行程。而不同行程在溝通時就會涉及訊息的序列化與反序列化的動作,因而造成CPU及Memory等額外的成本。

2. MSDTC必須要整合交易中所有的Resource Manager,包含跨AppDomain、跨Processes、跨Machines。各會可以想像當現實世界中,若你需要協調一群人的動作或意見時,有時即便是簡單的工作,中間的過程都可能是沒有效率的,甚至等待回應時間也是很漫長的。

因此各位可以體會到傳統交易程式是一種極端的二分法選擇,明確交易優點是速度快、吃資源少,每個Programmer都想要,但缺點是功能太簡單,也是每個Programmer都想提升的;那Enterprise Services的宣告式交易功能最強,也許能力上比較沒有可挑剔的,但是速度上又快不起來。故綜合以上兩點,可想而知Programmer心中會有多麼地掙扎,為什麼.NET不給我一個執行速度既快,功能又強的交易管理機制?好比男仕選擇女友或老婆時,一位美麗但不富有,另一位富有但不美麗,不知男仕心中會不有極度掙扎!?若這時出現了第三位,既美麗又富有,我想應該男仕也沒什麼好掙扎了,當然挑第三位。

相同的狀況也發生在Transaction程式的世界,傳統的兩種方法優缺點都過份極端,為了調合這種不完美,微軟推出了System.Transactions新世代的交易管理機制(或稱程式撰寫模型),它屬於輕量級的交易管理機制,執行速度可以和SqlTransaction之類的程式媲美,另一方面可以動態決定是否需要從Local Transaction升級成分散式交易間,最後達到的效能與功能的平衡點,總算讓人覺得還有另一個不錯的選擇。

而System.Transactions交易是屬於輕量級交易管理者(Lightweight Transaction Manager),對於交易程式的撰寫模型有兩個:(1)隱含交易程式撰寫模型,使用TransactionScope類別來建立,(2)明確交易程式撰 寫模型,使用Transaction或CommitableTransation類別來建立,System.Transactions可以從Local transaction交易視需要升級為Distributed Transaction分散式交易,這是最大的目的。

例如使用TransactionScope類別所建立的隱含交易程式:

1 //宣告TransationScope隱含交易

2 using (TransactionScope ts = newTransactionScope())

3 {

4 string connString = WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;

5 SqlConnection conn = newSqlConnection(connString);

6 conn.Open();

7

8 string strSQL = "INSERT INTO Employees(FirstName, LastName, City, Address) values (@paramFirstName,@paramLastName,@paramCity,@paramAddress)";

9 SqlCommand cmd = newSqlCommand(strSQL, conn);

10

11 try

12 {

13 cmd.Parameters.Add("@paramFirstName", SqlDbType.NVarChar, 20).Value = txtFirstName.Text;

14 cmd.Parameters.Add("@paramLastName", SqlDbType.NVarChar, 10).Value = txtLastName.Text;

15 cmd.Parameters.Add("@paramCity", SqlDbType.NVarChar, 15).Value = txtCity.Text;

16 cmd.Parameters.Add("@paramAddress", SqlDbType.NVarChar, 60).Value = txtAddress.Text;

17 cmd.ExecuteNonQuery();

18 txtMsg.Text = "新增資料成功,交易確認!";

19 ts.Complete();

20 }

21 catch

22 {

23 txtMsg.Text = "新增資料失敗,交易Rollback!";

24 }

25

26 finally

27 {

28 conn.Close();

29 conn.Dispose();

30 cmd.Dispose();

31 }

32 }

使用CommittableTransaction類別所建立的明確交易程式:

1 //宣告CommittableTransaction明確交易

2 using (CommittableTransaction tran = newCommittableTransaction())

3 {

4 string connString = WebConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;

5 SqlConnection conn = newSqlConnection(connString);

6 conn.Open();

7 conn.EnlistTransaction(tran); //登記加入明確交易

8

9 string strSQL = "INSERT INTO Employees(FirstName, LastName, City, Address) values (@paramFirstName,@paramLastName,@paramCity,@paramAddress)";

10 SqlCommand cmd = newSqlCommand(strSQL, conn);

11

12 try

13 {

14 cmd.Parameters.Add("@paramFirstName", SqlDbType.NVarChar, 20).Value = txtFirstName.Text;

15 cmd.Parameters.Add("@paramLastName", SqlDbType.NVarChar, 10).Value = txtLastName.Text;

16 cmd.Parameters.Add("@paramCity", SqlDbType.NVarChar, 15).Value = txtCity.Text;

17 cmd.Parameters.Add("@paramAddress", SqlDbType.NVarChar, 60).Value = txtAddress.Text;

18 cmd.ExecuteNonQuery();

19 txtMsg.Text = "新增資料成功,交易確認!";

20 throw new Exception("想反悔了,取消Insert!!!");

21 tran.Commit(); //確認交易

22 }

23 catch

24 {

25 txtMsg.Text = "新增資料失敗,交易Rollback!";

26 tran.Rollback(); //回復交易

27 }

28

29 finally

30 {

31 conn.Close();

32 conn.Dispose();

33 cmd.Dispose();

34 }

35 }

最後,學會了TransactionScope隱含交易及CommittableTransaction明確交易程式之撰寫,不過那並不是最主要之重點,而真正的重點卻是來自於LTM的特質,LTM在面對交易管理時,若可以在Local Transaction完成的,絕不會非得使用分散式交易管理,如此可達到成本與速度兼優的好處,而當Local Transaction不能應付交易時,則它又可以具備提升到分散式交易的延展性,並且不需要Programmer涉入太多的交易管理細節。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐