2009年2月8日

What’s ThreadLocalStorage (aka TLS)?

最近開始試圖解決公司底層元件的宿疾陳痾 -- 惡名昭彰的 MSDTC
以使用 TransactionScope 來說,為了確保系統中全程採用 Local Transaction,
重點在於在交易過程中必須使用單一的 connection,且不可以有開開關關的動作
 
(關於 MSDTC 的說明請參考附註中 Darkthread 大大的.NET分散式交易程式開發FAQ)

但是很不幸的,舊的底層元件(Entity)為了簡化外部程式的寫法, 主動把 connection 物件給包了起來,並且在每個 public 的 CRUD Method 中去 open & close connection,因此只要在 TransactionScope 中使用多個 Entity, 或者先呼叫某個 Entity 的 Select 再呼叫 Save(造成 connection 開關多次), 就會導致該交易從 Local Transaction 被 automatic escalate 為 MSDTC, 進而造成 MA 時莫大的痛苦

(幾乎每次 MSDTC 出錯時,根據當時的 System Configuration 都可以在網路上找到相對應的案例。也就是說,各種可能導致 MSDTC 出錯的環境組合幾乎是無窮盡的 =.=”)


為了在「避免舊系統大幅改寫」的前提下,修改底層元件的寫法以設法避免 MSDTC,
我們需要一個 Global 的地方以存放共用的 connection (以及相關的交易控制資料),
在一番討論 & survey 之後,決定採用 ThreadLocalStorage (簡稱 TLS) 這個技術。

以下是 TLS 的基本介紹:
  • TLS 的技術可以回溯到 Win32 multi-threaded programming,在 .NET 的世界中也有一套相對應的作法。
  • TLS 的基本原理是,在每個 thread 中分配一塊可以用來儲存資料的地方,只要在該 thread 中執行的 method 均可存取這些資料。
  • TLS 的一個好用之處,在於可在不修改現有程式碼(不管是改不動還是根本就沒有 source code)的情況下,在系統中增加(效能分析)用的 tracking information(有一點 AOP 的感覺)。對我目前面臨的問題來說,剛好可以當作 Global Data Storage 來儲存 connection 物件。
  • 在 TLS 中,一份資料對於某一組「thread + AppDomain」來說是 unique 的。TLS 不能像 .NET Remoting 技術那樣的 cross AppDomain boundary。
    (.NET Remoting 還蠻複雜的,看來沒時間仔細研究。不過以後會被 WCF 取代)
    image
  • 儲存於 TLS 的資料一律是 Object 的資料型態,因此必須自己 handle 轉型。
TLS 的基本程式寫法很簡單,可以參考這裡。雖然目前這個方法還沒有實際驗證過,
但根據手上的資料來看應該是可以解決 MSDTC 的問題。

我的小小 TLS 範例程式可以在這裡下載。

PS. 關於 MSDTC 的說明,可參考 Darkthread 大大在 Run!PC 上發表的文章,如果忘記這個連結位置的話,可以 google「darkthread TransactionScope」,在第二個 result「Browse by Tags - Darkthread」中就可以找到「.NET分散式交易程式開發FAQ」。

沒有留言:

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D