Try   HackMD

TransactionScope 咱們一起同進退,共患難

tags: ASP.NET C# SQL TransactionScope

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
關於儲存的那檔事

儲存:這份檔案需要先儲存,所以儲存步驟就放我這不要複製再貼上,call我就會處理
陳核:我要儲存!但是儲存前要先存些東西,真的不行複製過來我這嗎?
退回:我也要!我也要!我也要儲存但是需要前處理資料,而且跟陳核處理的部分不一樣耶!
結案:不用擔心我!我只要儲存就好,其他一律不處理跟負責。
刪除:恩 我應該不用儲存吧?反正儲存完也要刪掉,沒有要保留了不是嗎?

上面的故事,大家有沒有發現了什麼問題點

沒錯!顯而易見的東西叫做「儲存資料」,而且儲存的邏輯被規定放在某個function裡
即使有其他邏輯、需求需要在儲存前或儲存中作相對應處理,卻不能把儲存邏輯放在其他地方。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
要先說明為何不能將儲存方式多放在其他地方的原因
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

    1. 原始資料
var savedList = new List<string>() {"I got a book", "have to save"};
    1. 儲存資料 原始function
public async Task<bool> onlySaved(List<string> list){
    var result = false;
    
    using (var scope = new TransactionScope()){
        foreach (var saveObj in list)
        {
            if(string.IsNullOrEmpty(saveObj))
                await savingObject(saveObj);
        }
        scope.Complete();
        result = true;
    }
    return result;
}
    1. 儲存前 前處理
public async Task<bool> savedAndAdding(List<string> list){
    var result = false;
    
    using (var scope = new TransactionScope()){
        for (var i = 0; i < list.Count(); ++i)
        {
            var saveObj = string.Format("{0}. {1}", i, ist[i]);
            if(string.IsNullOrEmpty(saveObj))
                await savingObject(saveObj);
        }
        scope.Complete();
        result = true;
    }
    return result;
}

兩種差別儲存方式只有在儲存前整理、預先處理一些雜項,但實際上可能有更多資料需要。
而且不只處理,還需要顯示,導致更多因素讓儲存function到處被複製

這樣的缺點,會讓後續接手人員不好改,而且一改動就要從頭審查程式碼

接下來將以 C# 的 Transaction方式 進行介紹

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

:Memo: TransactionScope建構後可以分別傳入以下三種參數

  • Required : 當存在交易環境時則繼續使用,反之建立新的交易區塊,此為預設值。
  • RequiredNew : 必定建立新的交易區塊。
  • Suppress : 隱藏該交易區塊的內容,不影響原交易區塊。

測試方法詳查

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
點我連結

示意圖







graphname


cluster_c

A  交易區塊



a

B  交易區塊



經過上述的測試方式,結論有以下幾點

Ⅰ. TransactionScope.Required

  • Required 會偵測區塊外是否存在交易動作,若有則繼續使用,無則開立新的交易區塊。
  • 當TransactionScope區塊內包含Required時,外部的Scope若不Commit,即使內部 Commit 也不會進行更動

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
當外部不Commit時,內部即使Commit也不進行更動。

:A:

可以想像成上圖,當「B交易區塊」被呼叫時,「A交易區塊」已經產生等待中
這時「B交易區塊」會去使用「A交易區塊」,不會去產生新的一份交易區塊
可以視為「B交易區塊」的資料合併到「A交易區塊」內作動
所以整個「A、B交易區塊」皆可看成「A交易區塊
因此只要「A交易區塊不Commit,整大段的資料就不會變更

Ⅱ. TransactionScope.RequiredNew

  • 不管 RequiredNew 是否含有已存在的交易區塊,皆會開啟新的交易區塊做使用。

Ⅲ. TransactionScope.Suppress

  • 當有多種資料庫需要Transaction時,因各自權限不同,所以針對不可變更的資料庫進行TransactionScope設定則使用Suppress,不必建立交易區塊,也不用Commit就會即時更新

結論

根據以上測試的結論來看,可以整理成下列表來看

TransactionScope選擇 Commit (外部Trasaction)Commit 內部資料更新結果
Required Yes Yes 成功
Required No Yes 成功
Required Yes No 失敗
Required No No 失敗
RequiredNew Yes Yes 成功
RequiredNew No Yes 失敗
RequiredNew Yes No 成功
RequiredNew No No 失敗
Suppress Yes Yes 成功
Suppress No Yes 成功
Suppress Yes No 成功
Suppress No No 成功

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Required時有外部看外部Transaction,沒外部就看內部Transaction

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
RequiredNew就只看內部Transaction

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Suppress哪邊都不看


Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
連結