COM+分佈事務處理(選擇自 ccBoy)

事務何時開始又何時結束
瞭解事務的開始和結束的過程可以使我們從一個事務邊界裏考察每個參與對象的行爲和事務的邊界情況。
COM+何時開始一個事務?在下面兩種情況下COM+將自動開始一個事務:
1.      當一個非事務屬性的Client調用了一個標識有需要或需要新事務的COM+組件
2.      當一個有事務屬性的Client調用了一個標識有需要新事務的COM+組件
 
當COM+確定一個對象需要一個新的事務,那麼它會首先在當前對象的位置開始一個事務,接着它在下面一些步驟進行一些操作:
1. COM+創建一個環境(Context)對象,設置其JIT activation和synchronization屬性爲需要,並且設置內部維護的consistent和done 標誌位。
2. COM+通知DTC將開始一個事務,DTC配置一個物理的事務
3. DTC產生一個新的事務並將標識這個事務的GUID標識返回給COM+,事務標識將建立一個事務環境邊界,所有參與事務的對象將分享這個標識。COM+將這個事務的引用保存到Context中
4. 當Client建立這個對象時,COM+在這個事務邊界的環境中激活它
 
事務邊界中的第一個對象是很特別的,它就是我們一般所說的根對象,一個事務中只能有一個根對象,根對象之下的其它對象被稱爲內部對象。
 
COM+何時結束一個事務?在下面三種情況下COM+將結束一個事務其結果是提交或回滾事務。
1. 事務的執行超過了期限,那麼COM+將自動結束在超時期間沒有提交的事務,和事務相關的所有對象不再處於激活狀態(deactivating),事務回滾。一般缺省的事務超時時間是60秒。
2. 根對象在一個調用中完成它的工作,COM+釋放它的引用(代理和存根還在),之後根對象不再處於激活狀態,整個事務開始嘗試提交。
3. 根對象被Client釋放,COM+釋放對象的引用(代理先沒有了存根也沒有了),之後根對象不再處於激活狀態,整個事務開始嘗試提交。
 
COM+提交或放棄事務
       爲了有效的工作,COM+在每個環境(Context)中維護着兩個標誌位consistent和done。這兩個標誌
位影響事務是提交還是放棄,開發人員靠改變這兩個標誌位來告訴COM+自己對事務的觀點,COM+根據
這兩個標誌位的狀態在通知DTC該如何和RM進行交互。事實上有一個真相一直被我們忽略:
      具有事務屬性的對象沒有參與著名的兩段提交過程(也就是說沒有見證到整個事務的結果),只是所
有應徵RM和DTC完成了這個過程(評票和實施,並且宣佈結果)。整個事務邊界中的所有對象僅是對事務
是否提交進行了投票,當所有的組件同意後,COM+將統計這些投票並把最終的一個結果告訴DTC,你曾
經爲我創建的某個事務(由GUID標識的)可以提交了,DTC請求所有應徵的RM也提交各自的改變。而此
時曾經參與投票的所有對象已經銷燬或是去了對象池,總之它們已經不再處於激活狀態了。也就是說根對
象在調用SetComplete之後簡單的獲得了一個簡單的S_OK返回(事務何時開始和結束它根本不知道),其
他對象對事務結果更是一無所知(只是在臨死前投下自己的一票),兩段提交過程可能失敗。那麼COM+
會更改原來根對象獲得的S_OK的返回值(CONTEXT_E_ABORTED),最後只有根對象的Client知道事務
最終的結果。當然根事務如果調用SetAbort,那麼結果是預先可以知道的,但根事務象上面說的一樣,仍
然不是處於激活狀態。簡單的說,根對象通過請求被釋放來強迫COM+進入它的事務表決。根對象釋放之
後,COM+也會釋放事務域裏的所有對象,因此這之前所有對象的暫時表決必須在COM+統計投票之前確
定下來(這是最後期限),之後COM+知道是提交還是回滾事務,事務被強迫隔離起來不再允許任何線程
或對象進入(隔離是JIT激活要求的,如果不隔離對象還可以再進來或是對象可能帶着狀態參與到下一次的
其它事務中,而這種隔離保證是靠同步域(另外一個)來做到的,所以整個事務一直到最後都是安全
的)。
開發人員如何控制這兩個標誌位呢,特別是如果自己實現事務機制時,我們必須清楚這個投票算法。
下面的表列舉我們使用的方法來修改這兩個標誌位:

可以使用的方法或函數
Consistent Bit
Done Bit
IObjectControl::SetComplete
True
True
IObjectControl::SetAbort
False
True
IObjectControl::EnableCommit (default)
True
False
IObjectControl::DisableCommit
False
False
IContextState::Get/SetMyTransactionVote
 
根據傳入參數
IContextState::Get/StateDeactivateOnReturn
根據傳入參數
 
COM+根據下面的規則使用這兩個標誌位來收集投票:
1. 缺省的情況下,COM+新建立一個環境(Context)時,consistent設置爲true,done位被設置成false,也就是表中列的EnableCommit的情況
2. COM+將在當前函數返回時檢查,如果done 位是true,那麼COM+將使這個對象失去激活(deactivate),否則是false,COM+則繼續保留這個對象。
3. COM+只有在方法調用返回或是當一個對象失去激活狀態時檢查done位的值,如果爲true,那麼COM+才注意consistent 位的值,如果consistent位是true,那麼表明它贊成提交,否則表明要回滾。
4. 只有在對象失去激活時,COM+纔讀取事務表決。如果對象不向COM+請求釋放,那麼就在最後Client釋放它之後,讀取表決。即只有當done位爲true時,COM+纔開始讀取cnsistent標誌位。
5. 由於整個事務邊界中的所有對象將共享這兩個標誌位,所以每個標誌位都在對象失去激活前都可以設置多次和進行多次改變(上面說的“對象的暫時表決”),COM+只取最後一次改變作爲計數。
根據上面的規則,我們就可以在程序中進行這樣的仿真以實現自己的事務機制:

缺省(class構造)
提交前
回滾前
暫時不提交
提交暫時不提交的
IsHappy = true
IsDone = false
 
IsDone = true
IsHappy=false
IsDone = true
 
IsDone = false
 
IsDone = true
IsHappy 表示consistent標誌位,IsDone表示done標誌位,然後我們的類裏可以這樣判斷:

if(CurrentTranscationContext.IsDone)
{
if(CurrentTranscationContext.IsHappy)
{ //done== true && consistent== true
CurrentTranscationContext.Commit();
}
else
{ // done == true && consistent == false
CurrentTranscationContext.Rollback();
}
CurrentTranscationContext = null;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章