7.6. 流程同步
為了進(jìn)行流程同步建模,在執(zhí)行中這是一個(gè)父子樹形結(jié)構(gòu)。 這個(gè)想法是執(zhí)行主路徑是樹的根。 流程的主路徑也被稱作流程實(shí)例。 當(dāng)在給定流程定義上啟動(dòng)或創(chuàng)建一個(gè)新流程實(shí)例時(shí), 執(zhí)行便被創(chuàng)建。
現(xiàn)在,因?yàn)閳?zhí)行的主路徑和流程實(shí)例是相同對象, 這保證了用法的簡單, 在沒有同步情況的簡單流程下。
基本執(zhí)行結(jié)構(gòu)的UML類圖
圖 7.6. 基本執(zhí)行結(jié)構(gòu)的UML類圖
為了建立執(zhí)行的多同步路徑,活動(dòng)實(shí)現(xiàn)比如一個(gè)分支或切分 創(chuàng)建子執(zhí)行, 使用ActivityExecution.createExecution方法。 活動(dòng)實(shí)現(xiàn)比如結(jié)合或合并可以停止流程的這些同步路徑, 通過調(diào)用執(zhí)行同步的stop方法。
只有葉子執(zhí)行可以激活,非葉子執(zhí)行應(yīng)該不是激活的。 這個(gè)執(zhí)行的樹形結(jié)構(gòu)沒有堅(jiān)持一個(gè)同步或結(jié)合行為的特殊類型。 它從事著分支或和切分 和結(jié)合或和合并來使用執(zhí)行樹結(jié)構(gòu), 用任何方式,他們想定義期望的同步行為。 這里我們看一個(gè)同步執(zhí)行的例子。
執(zhí)行的同步路徑
圖 7.7. 執(zhí)行的同步路徑
這里有執(zhí)行的一個(gè)付款和一個(gè)發(fā)貨路徑。 在這種情況,水平線上的活動(dòng)展示了分支和結(jié)合。這個(gè)執(zhí)行顯示了三個(gè)執(zhí)行。 執(zhí)行的主路徑不是激活的(顯示成灰色) 執(zhí)行的付款和發(fā)貨路徑是激活的,分別指向了 bill和ship活動(dòng)。
從事活動(dòng)行為的實(shí)現(xiàn),是他們想使用的執(zhí)行結(jié)構(gòu)。 假設(shè)多個(gè)任務(wù)必須在執(zhí)行進(jìn)行之前完成。 活動(dòng)行為可以為這個(gè)產(chǎn)生一系列子執(zhí)行。
或者可以選擇,任務(wù)組件可以支持任務(wù)組, 分配給單獨(dú)的執(zhí)行。在那種情況, 任務(wù)組件成為同步任務(wù)的響應(yīng),
因此把這個(gè)責(zé)任移動(dòng)到執(zhí)行樹形結(jié)構(gòu)范圍之外。
7.7. 異常處理器
在所有分配到流程的代碼中,像 Activity,EventListeners和 Condition,可能分配給異常處理器。
這可以想成是把這些實(shí)現(xiàn)的方法實(shí)現(xiàn)包含在try-catch塊中。 但是為了構(gòu)建更多可復(fù)用的構(gòu)建塊, 為了委派類和異常處理邏輯,
異常處理器可以添加到核心流程模型中。
一個(gè)異常處理器可以分配給任何流程元素。 當(dāng)一個(gè)異常發(fā)生在一個(gè)委派類中,一個(gè)匹配的異常處理器就會被找到。 如果找到了一個(gè)這樣的異常處理器,它會有一個(gè)處理這個(gè)異常的機(jī)會。
如果一個(gè)異常處理器處理完成,沒有出現(xiàn)問題,然后這個(gè)異常會 被認(rèn)為是處理了,就會在委派代碼調(diào)用后繼續(xù)。 比如,一個(gè)轉(zhuǎn)移有三個(gè)動(dòng)作,第二個(gè)動(dòng)作拋出一個(gè)異常, 這個(gè)異常被異常處理器處理,然后
編寫自動(dòng)活動(dòng),異常處理器提醒是很容易的。 默認(rèn)是任意執(zhí)行。沒有方法需要在執(zhí)行中調(diào)用。
所以如果一個(gè)自動(dòng)活動(dòng)拋出一個(gè)異常,被異常處理器處理, 這個(gè)執(zhí)行會在這個(gè)執(zhí)行后繼續(xù)執(zhí)行。這對于控制流向活動(dòng)
就會有一個(gè)更大的困難。它們可能需要包含try-finally塊 來調(diào)用執(zhí)行中對應(yīng)的方法,在異常處理器
獲得一個(gè)機(jī)會來處理異常。比如,如果活動(dòng)是等待狀態(tài), 然后發(fā)生了一個(gè)異常,這里就會有一個(gè)風(fēng)險(xiǎn),線程會跳出
execution.waitForSignal()的調(diào)用, 導(dǎo)致執(zhí)行在這個(gè)活動(dòng)以后繼續(xù)執(zhí)行。
TODO: exceptionhandler.isRethrowMasked
TODO: transactional exception handlers
TODO: we never catch errors
7.8. 流程修改
TODO: 流程修改
7.9. 鎖定和流程狀態(tài)
一個(gè)執(zhí)行的狀態(tài)不是激活就是鎖定。 一個(gè)激活的執(zhí)行不是執(zhí)行就是等待外部觸發(fā)器。 如果一個(gè)執(zhí)行不是STATE_ACTIVE,那么它就是被鎖定。 一個(gè)鎖定的執(zhí)行是只讀的,不能接受任何外部觸發(fā)器。
當(dāng)一個(gè)新執(zhí)行被創(chuàng)建時(shí),它是STATE_ACTIVE。 為了把狀態(tài)修改成鎖定狀態(tài),使用lock(String)。一些STATE_*常量 被提供了,它們演示了最常用的鎖定狀態(tài)。 但是在圖片中的'...'狀態(tài)展示了任何字符串 都可以作為狀態(tài)提供給lock方法。
執(zhí)行的狀態(tài)
圖 7.8. 執(zhí)行的狀態(tài)
如果一個(gè)執(zhí)行被鎖定,修改執(zhí)行的方法會 拋出一個(gè)PvmException,信息會引用真實(shí)的鎖定狀態(tài)。
觸發(fā)事件,更新變量,更新優(yōu)先級,添加注釋 不會當(dāng)做是修改執(zhí)行。 子節(jié)點(diǎn)的創(chuàng)建和刪除也不會檢測,
這意味著那些方法可以被外部API客戶和活動(dòng)行為調(diào)用, 即使執(zhí)行在鎖定狀態(tài)。
確保比較getState()和STATE_*常量時(shí) 使用.equals,不要使用'==',因?yàn)槿绻麍?zhí)行從持久存儲加載。 會創(chuàng)建一個(gè)新字符串,而不是使用常量。
一個(gè)執(zhí)行實(shí)現(xiàn)會被鎖定:
* 當(dāng)它結(jié)束
* 當(dāng)它暫停
* 在異步延續(xù)過程中
更多的,鎖定可以被活動(dòng)實(shí)現(xiàn)使用, 讓執(zhí)行在等待狀態(tài)下只讀,然后為這個(gè)執(zhí)行傳遞 的外部實(shí)例就像這樣:
* 一個(gè)人員任務(wù)
* 一個(gè)服務(wù)調(diào)用
* 一個(gè)等待狀態(tài)當(dāng)探測器檢測一個(gè)文件的出現(xiàn)時(shí)就結(jié)束
在這些情況,策略是外部實(shí)例應(yīng)該獲得 執(zhí)行的完全控制,因?yàn)樗胍刂剖裁磻?yīng)該允許,什么不應(yīng)該。 為了獲得那種控制,他們鎖定了執(zhí)行,所以所有內(nèi)部交互 必須通過外部實(shí)例傳遞。
一個(gè)創(chuàng)建外部實(shí)例的主要原因是, 它們可以在執(zhí)行已經(jīng)執(zhí)行過還存在。比如, 在服務(wù)調(diào)用的情況,定時(shí)器可以導(dǎo)致執(zhí)行獲得超時(shí)轉(zhuǎn)移。
當(dāng)響應(yīng)在超時(shí)后到達(dá),服務(wù)調(diào)用實(shí)例應(yīng)該 確認(rèn)它沒有signal這個(gè)執(zhí)行。所以服務(wù)調(diào)用可以看做 一個(gè)活動(dòng)實(shí)例(活動(dòng)實(shí)例)
是對活動(dòng)每個(gè)執(zhí)行的唯一實(shí)例。
外部實(shí)例它們自己負(fù)責(zé)管理執(zhí)行鎖定。 如果定時(shí)器和客戶端應(yīng)用結(jié)果是選擇 外部實(shí)例,而不是直接選擇執(zhí)行,然后在理論上是不必要的。 它是從事活動(dòng)行為實(shí)現(xiàn),無論它希望 執(zhí)行鎖定還是解鎖。
posted on 2009-06-26 12:05
卡宴 閱讀(1084)
評論(0) 編輯 收藏 所屬分類:
jBPM