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