jbpm5.1介紹(3)

在您好的應用程序中使用一個新的流程

流程處理 

(1)你需要建立一個知識庫,其中包含過程定義

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource("MyProcess.bpmn2"),
              ResourceType.BPMN2 );

  加入你的進程生成器(可以添加多個進程您可以創建一個新的知識基礎這樣的

KnowledgeBase kbase = kbuilder.newKnowledgeBase();

  注意,這將拋出一個異常如果知識庫包含錯誤(因爲它不能正確地分析您的流程

(2)你需要創建一個會話溝通流程引擎啓動過程啓動過程

啓動過程:啓動一個特定的進程,你會需要調用您的會話startProcess方法,並傳遞您要啓動進程的ID例如:

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
ksession.startProcess("com.sample.hello");

startProcess方法參數需要啓動的進程ID當定義一個過程,需要作爲一個過程的財產例如在Eclipse屬性視圖顯示當您單擊過程中背景畫布指定進程ID

當您啓動的過程中,你可以指定額外的參數用來傳遞額外的輸入數據的過程中,使用startProcess絃樂進程ID地圖參數方法額外參數是一個名稱 - 值對集合這些參數將被複制到新創建的進程實例頂層變量的過程,所以他們可以你的進程餘下直接訪問

數據

雖然流程圖指定過程控制重點通常也有必要的過程從數據的角度整個執行過程數據可以檢索,存儲,傳遞和使用

對於運行時的數據存儲執行過程中,過程變量都可以使用。變量是一個名稱和一個數據類型定義這可能是一個基本數據類型布爾,INT,或String任何Object的子類變量可以定義一個變量的範圍頂層範圍過程本身變量的範圍Subscopes可以定義使用一個子進程子範圍定義變量只在該範圍內節點訪問

每當訪問一個變量,這個進程將尋找合適的變量範圍定義變量變量作用域嵌套不允許的。節點總是會尋找其父容器一個變量如果無法找到該變量,一個人的父容器等等,直到達到流程實例本身如果無法找到該變量讀訪問產量寫訪問會產生錯誤消息繼續執行的過程

變量可以用各種方式

  • 流程級別的變量可以設置啓動時提供的參數映射到thestartProcess方法調用一個過程這些參數將作爲進程範圍變量
  • 腳本操作,只需直接使用腳本本地參數變量的名稱可以訪問變量。例如,如果程序定義了一個變量類型org.jbpm.Person”的過程中在這個過程中腳本可以訪問此直接person.setAge(10);更改一個腳本中的變量可以通過知識背景下kcontext.setVariable(variableName, value);
  • 服務任務重複使用過程可以通過向外界另一個進程實例過程變量變量映射一個傳出參數例如,服務任務參數映射可以定義的過程變量x被映射到一個任務參數y對前被調用服務您還可以注入一個硬編碼參數字符串使用{表達式}過程變量值例如,可以定義一個人任務描述您需要聯絡人#{person.getName()}其中是一個過程變量這個表達式將取代實際名稱服務時需要調用同樣的服務可重複使用的子進程結果也可以複製使用結果映射到一個變量
  • 各種其他節點也可以訪問數據。例如事件節點可以存儲在變量事件關聯的數據檢查更多信息,不同的節點類型的屬性

最後,流程和規則進入全局,即全局變量知識會話數據的全局行動就像變量直接訪問全局需要定義作爲這一進程的一部分纔可以使用例如按一下指定動作腳本在Eclipse行動的屬性編輯器全局按鈕您可以定義全局您還可以設置一個全球從外面使用ksession.setGlobal名稱,值從內部使用kcontext.getKnowledgeRuntime()過程腳本價值在setglobal名稱,值;

約束

約束可用於在不同的地點你的流程例如一個不同的網關jBPM支持兩種類型的約束

  • 守則約束的布爾表達式他們到達直接評價我們目前支持兩種方言表達這些代碼限制Java和MVELJava和MVEL代碼限制直接訪問,並在這個過程中定義全局變量下面一個有效的Java代碼的約束在這個過程中一個變量一個例子return person.getAge()>20;一個類似的例子是一個有效MVEL代碼約束:return person.age > 20;
  • 規則約束等於正常Drools的規則條件他們使用了Drools規則語言語法表達可能複雜的約束這些規則可以任何其他規則是指工作內存中數據他們還可以直接全局下面一個有效的規則約束例子:Person( age > 20 )

規則約束沒有直接訪問內部的過程定義的變量不過這是可能加入流程實例工作記憶你的規則約束匹配過程實例的規則約束當前進程的實例我們已經添加了特殊的邏輯,以確保變量類型WorkflowProcessInstance流程實例只匹配當前進程的實例,而不是工作內存中其他進程實例注意不過你是負責自己插入到會話的過程實例可能的話,更新它,例如,使用Java代碼你的進程進入或退出或明確的行動規則的約束下面的例子將一個在變量“名稱”的過程中存儲的值相同的名稱搜索

processInstance : WorkflowProcessInstance()
Person( name == ( processInstance.getVariable("name") ) )
# add more constraints here ...

動作角本

動作腳本可以使用不同的方式

  • 腳本任務
  • 進入或者退出動作中

操作全局過程預定義變量kcontext定義的變量訪問此變量的類型org.drools.runtime.process.ProcessContext用於多個任務

獲取當前節點的實例(如適用)節點的實例,如它的名稱和類型數據可以查詢您還可以取消當前節點的實例

NodeInstance node = kcontext.getNodeInstance();
String name = node.getNodeName();

獲取當前進程的實例可以查詢流程實例數據名稱,ID,進程ID,中止暗示內部事件

ProcessInstance proc = kcontext.getProcessInstance();
proc.signalEvent( type, eventObject );

獲取或設置變量的值

訪問知識庫中運行允許喜歡的東西開始一個進程信號(外部)事件插入數據

jBPM的目前支持兩種方言Java和MVELJava行動應該是有效的Java代碼MVEL行動可以使用的業務腳本語言MVEL表達行動MVEL接受任何有效Java代碼此外提供支持嵌套參數訪問(例如,person.name,而不是person.getName許多其他腳本改進因此MVEL表達式爲商業用戶方便例如,一個動作,打印出在“請求者的過程變量名稱看起來像這樣

// Java dialect
System.out.println( person.getName() );
 
//  MVEL dialect
System.out.println( person.name );

活動

執行過程流程引擎可以確保所有相關的任務是根據工藝方案執行請求執行的工作項目等待結果然而,它也有可能這一進程應作出迴應直接流程引擎要求事件明確代表這些事件的過程允許指定過程中應如何應對此類事件過程作者

事件一個類型,可能與他們相關的數據用戶可以自由定義自己的事件類型及其相關數據

一個進程可以指定如何使用消息事件響應的事件一個事件節點需要指定類型的事件節點感興趣它也可以定義一個變量的名字,這將收到與該事件相關的數據這使得在這個過程中後續節點訪問事件數據根據該數據採取適當的行動

事件可能標誌着一個多種方式過程正在運行的實例

內部事件:任何一個進程內的行動(例如,行動節點行動一些節點進入退出行動信號內部事件的發生,周圍流程實例使用類似代碼以下內容:

kcontext.getProcessInstance().signalEvent(type, eventData);

外部事件事件通知一個流程實例可以外面用,如代碼

processInstance.signalEvent(type, eventData);

使用事件相關而是直接通知一個流程實例外部事件,它也可以讓發動機自動確定流程實例可能會使用事件的相關性,這是基於事件類型事件感興趣這樣的事件發生一個流程實例包含事件節點某種類型的外部事件通知信號此類事件流程引擎代碼,如​​:

ksession.signalEvent(type, eventData);

事件也可以被用來啓動一個進程每當消息開始事件定義一個特定類型的事件觸發將會啓動新的流程實例,每次事件的類型信號流程引擎

計時器

計時器等待一個預定的時間觸發前一次或多次他們可以使用一段時間觸發一定的邏輯關係定期重複某些動作

定時器節點設置一個延遲和一個時期延遲指定的時間節點激活等待觸發定時器首次這一時期定義隨後觸發激活之間時間期間,一個單次觸發定時器0的結果

表達的形式[#][#H] [#M] [#S] [[MS]這意味着您可以指定天,小時,分鐘multiseconds這是默認的,如果你指定任何數量例如,表達1H”將等待觸發定時器(再次)一小時。

負責確保在適當的時候觸發定時器得到定時服務定時器也被取消意味着將不再被觸發定時器

定時器可用於一個進程內兩個方面
計時器事件可能會增加流動過程其激活啓動定時器它觸發一次或多次,它會激活定時器節點的繼任者這意味着,以積極的時期傳出連接定時器觸發多次取消定時器節點取消了相關的計時器,在這之後沒有更多觸發發生
定時器可以一個子進程作爲一個邊界事件但是,這是目前唯一可能直接在XML我們將加入支持在新BPMN2編輯器以圖形方式指定

更新流程

隨着時間推移,流程可能演變例如因爲這個過程本身需要加以改進,由於不斷變化的需求其實,你真的不能更新的過程你只能部署一個新版本的過程中舊的過程依然存在。這是因爲現有流程實例可能還需要這一過程定義因此,新過程應該有一個不同的ID雖然名稱可能是相同的可以使用的版本參數表明,當一個進程更新版本參數只是一個字符串,而不是進程的框架本身驗證所以你可以選擇自己的格式用於指定小/大的更新等)

每當一個更新過程重要的是,以確定哪些應該發生已經運行的進程實例不同的策略之一,可以考慮爲每個運行實例

步驟操作:正在運行的進程實例收益爲正常,因爲它是定義流程實例啓動下面的過程(定義)因此,已經運行實例進行過程中彷彿從來沒有更新實例可以開始使用更新的過程

中止並重新啓動已經運行實例被中止。如果有必要,可以重新啓動的過程實例使用流程定義

傳輸過程實例遷移到流程定義含義 -一旦它被成功遷移 - 將繼續執行基礎更新的過程邏輯

默認情況下jBPM的使用進行方法意味着可以部署同一進程多個版本,但現有流程實例簡單的啓動流程實例時所使用流程定義基礎繼續執行總是可以被中止正在運行的進程實例,以及當然在使用過程中的管理API過程實例遷移是比較困難的下面的段落解釋

流程實例的遷移

一個流程實例包含所有運行中的信息需要繼續執行一些稍後的時間點這包括所有鏈接到這個過程實例(如變量數據,而且在這個過程中當前狀態對於當前處於活動狀態的每個節點一個節點實例是用來表示這個節點的實例也可以包含額外的狀態鏈接到特定節點執行不同類型的節點實例每個類型的節點之一

一個流程實例只包含運行時狀態鏈接到一個特定的進程間接使用ID引用表示執行這個流程實例(明確的定義和運行時狀態分離,需要遵循流程邏輯允許重用跨越這個過程中,最大限度地減少運行時的狀態基礎所有流程實例定義因此,更新一個正在運行的進程實例所以它使用了新的進程邏輯,而不是到新的版本是一個簡單的改變從舊新的ID引用進程ID問題

但是,這並沒有考慮到流程實例狀態變量實例節點實例以及可能需要遷移僅擴展的過程所有現有等待狀態保持情況下這是非常簡單,流程實例運行狀態並不需要改變然而,也有可能是一個sofisticated映射是必要的例如,現有等待狀態被刪除,分割多個等待狀態等待在該國現有流程實例,不能簡單地更新或者引入一個新的進程變量該變量可能需要initiazed正確因此它可以更新過程中其餘部分使用

WorkflowProcessInstanceUpgrader可以使用工作流過程實例升級到一個新流程實例當然,您需要提供流程實例和進程ID默認情況下,jBPM將自動新節點具有相同的ID實例映射舊節點實例但是你可以提供一個舊的(唯一的)節點ID映射到新的節點ID惟一的節點ID節點ID,其父母節點ID冒號inbetween之前允許唯一標識一個節點使用複合節點節點ID節點容器只有獨特新的節點ID簡直是新的節點ID節點容器所以這裏沒有惟一的節點ID只是新的節點ID下面的代碼片段顯示了一個簡單例子

// create the session and start the process "com.sample.process"
KnowledgeBuilder kbuilder = ...
StatefulKnowledgeSession ksession = ...
ProcessInstance processInstance = ksession.startProcess("com.sample.process");
 
// add a new version of the process "com.sample.process2"
kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(..., ResourceType.BPMN2);
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
 
// migrate process instance to new version
Map<String, Long> mapping = newHashMap<String, Long>();
// top level node 2 is mapped to a new node with id 3
mapping.put("2", 3L);
// node 2, which is part of composite node 5, is mapped to a new node with id 4
mapping.put("5.2", 4L);
WorkflowProcessInstanceUpgrader.upgradeProcessInstance(
   ksession, processInstance.getId(),
   "com.sample.process2", mapping);

如果這種映射仍然不足,仍然可以描述自己的自定義映射器針對具體情況請務必先斷開流程實例,相應改變狀態,然後重新連接的過程實例類似如何WorkflowProcessinstanceUpgrader

業務流程模型和符號(BPMN)2.0規範

BPMN的主要目標是提供一個符號,是所有業務用戶容易理解的,
從創建進程的初稿,業務分析師,技術開發
負責實施的技術,將執行這些進程,並最終到
商界人士將管理和監視這些進程。“

業務流程模型符號(BPMN)2.0規範,不僅定義了一個標準如何以圖形方式表示業務流程BPMN1.x的OMG規範,但現在還包括執行定義的元素語義XML格式股)如何存儲過程定義

jBPM5允許執行使用BPMN 2.0的XML格式定義流程意味着,您可以使用所有不同jBPM5模具模型執行管理和監控您的業務流程指定可執行的業務流程使用BPMN2.0格式事實上,完整BPMN 2.0規範還包括如何表示編排和協作事情細節然而jBPM項目重點部分,可用於指定可執行流程規範

BPMN中可執行文件的進程包括不同類型節點連接到對方使用順序BPMN 2.0規範定義了三種主要類型的節點

事件它們用於模型中的特定事件發生這可能是一個開始事件(即用來指示的過程中開始結束事件定義過程結束子流中間事件指示的執行過程中可能出現事件過程)。

活動:這些定義需要執行過程中執行不同的動作存在不同類型任務活動的類型取決於您嘗試模型(如人工的任務,服務任務等)actvities也可以嵌套使用不同類型子進程

網關:可以被用來定義多個路徑的過程中根據網關類型,這些可能表明並行執行選擇等

jBPM5沒有實現BPMN 2.0規範定義的所有元素和屬性然而我們支持一個顯著子集,包括可執行的流程,可使用最常見的節點類型這包括幾乎所有元素,並BPMN 2.0規範共同的可執行文件”子類一些額外的元素屬性我們相信擴展定義屬性以及在這方面寶貴下面可以找到全套支持元素和屬性但它包含元素

流程對象包括

  • Flow objects
    • Events         
      • Start Event (None, Conditional, Signal, Message, Timer)
      • End Event (None, Terminate, Error, Escalation, Signal, Message, Compensation)
      • Intermediate Catch Event (Signal, Timer, Conditional, Message)
      • Intermediate Throw Event (None, Signal, Escalation, Message, Compensation)
      • Non-interrupting Boundary Event (Escalation, Timer)
      • Interrupting Boundary Event (Escalation, Error, Timer, Compensation)
    • Activities         
      • Script Task
      • Task
      • Service Task
      • User Task
      • Business Rule Task
      • Manual Task
      • Send Task
      • Receive Task
      • Reusable Sub-Process (Call Activity)
      • Embedded Sub-Process
      • Ad-Hoc Sub-Process
      • Data-Object
    • Gateways         
      • Diverging             
        • Exclusive
        • Inclusive
        • Parallel
        • Event-Based
      • Converging             
        • Exclusive
        • Parallel
    • Lanes
  • Data
    • Java type language
    • Process properties
    • Embedded Sub-Process properties
    • Activity properties
  • Connecting objects
    • Sequence flow

例如,考慮下面的“你好世界BPMN 2.0的過程中,它什麼也不做一個“Hello World”的說法時,過程開始

這個過程的可執行版本使用BPMN 2.0的XML表示看起來像這樣

<?xml version="1.0"encoding="UTF-8"?>
<definitions id="Definition"
             targetNamespace="http://www.example.org/MinimalExample"
             typeLanguage="http://www.java.com/javaTypes"
             expressionLanguage="http://www.mvel.org/2.0"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
             xs:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
             xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
             xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
             xmlns:tns="http://www.jboss.org/drools">
 
  <process processType="Private"isExecutable="true" id="com.sample.HelloWorld" name="Hello World" >
 
    <!-- nodes -->
    <startEvent id="_1"name="StartProcess" />
    <scriptTask id="_2"name="Hello" >
      <script>System.out.println("Hello World");</script>
    </scriptTask>
    <endEvent id="_3"name="EndProcess" >
        <terminateEventDefinition/>
    </endEvent>
 
    <!-- connections -->
    <sequenceFlow id="_1-_2"sourceRef="_1" targetRef="_2" />
    <sequenceFlow id="_2-_3"sourceRef="_2" targetRef="_3" />
 
  </process>
 
  <bpmndi:BPMNDiagram>
    <bpmndi:BPMNPlane bpmnElement="Minimal">
      <bpmndi:BPMNShape bpmnElement="_1">
        <dc:Bounds x="15"y="91" width="48" height="48"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_2">
        <dc:Bounds x="95"y="88" width="83" height="48"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3">
        <dc:Bounds x="258"y="86" width="48" height="48"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_1-_2">
        <di:waypoint x="39"y="115" />
        <di:waypoint x="75"y="46" />
        <di:waypoint x="136"y="112" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_2-_3">
        <di:waypoint x="136"y="112" />
        <di:waypoint x="240"y="240" />
        <di:waypoint x="282"y="110" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
 
</definitions>

創建自己的過程使用BPMN 2.0的格式你可以

創建一個新的流文件使用DroolsEclipse插件嚮導嚮導的最後一頁確保選擇的Drools5.1的代碼兼容性使用BPMN 2.0的XML格式這將創建一個新的進程但是請注意,這是不完全的BPMN 2.0編輯,因爲它仍然使用不同屬性的名稱但它確實保存過程中使用有效BPMN2.0的語法另外請注意,編輯器不支持所有節點類型和已執行引擎支持的屬性

設計師是一個開源基於Web的編輯器,支持BPMN2.0格式我們已經嵌入到GuvnorBPMN 2.0的流程可視化和編輯你可以使用Designer獨立或集成創建/編輯BPMN 2.0流程然後出口到BPMN 2.0的格式或將其保存Guvnor,使他們能夠執行

正在創建一個BPMN2的Eclipse插件支持完整的BPMN2規範這是目前仍在開發中只支持數量有限結構和屬性,但已經可以用來創建簡單BPMN2流程創建一個新的BPMN2的這個編輯器文件使用嚮導例子創建一個新的BPMN2的文件,這將產生一個BPMN2文件和一個。珠三角文件包含圖形信息雙擊珠三角文件使用的圖形化編輯編輯該文件

通過直接寫入XML您可以隨時手動創建BPMN 2.0的流程文件您可以BPMN 2.0的XSD驗證你的流程語法Eclipse插件使用驗證器來檢查你的模型的語法和完整性

下面的代碼片段顯示如何加載到知識庫一個BPMN2的過程......

private staticKnowledgeBase createKnowledgeBase() throws Exception {
  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
  kbuilder.add(ResourceFactory.newClassPathResource("sample.bpmn2"), ResourceType.BPMN2);
  returnkbuilder.newKnowledgeBase();
}

 

... ...如何執行此過程中......

KnowledgeBase kbase = createKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
ksession.startProcess("com.sample.HelloWorld");

持久化和轉換

jBPM的持久存儲允許某些信息流程的運行時狀態歷史信息

1)運行時狀態

每當啓動一個過程一個過程實例被創建,它代表的過程這種特定情況下執行例如,執行過程中指定如何處理銷售訂單一個流程實例創建要求每個銷售流程實例代表當前的執行狀態,這種特定情況下包含所有相關信息流程實例注意,它僅包含最小運行狀態需要繼續這一進程的實例執行一段時間後,但它不包括這一進程的實例歷史信息如果該信息不再需要流程實例

執行過程運行狀態可以持久的,例如在數據庫中這使得恢復意外故障情況所有正在運行的進程執行狀態或者暫時從內存中刪除正在運行的實例在一段時間後恢復它們jBPM的允許您插入不同持久性策略默認情況下,如果你不配置流程引擎否則流程實例沒有持久性

二進制持久性

jBPM提供了一個二進制持久性機制允許您保存爲二進制數據一個流程實例狀態通過這種方式,所有正在運行的進程實例狀態總是可以被儲存一個持久位置注意這些二進制數據通常都比較小,因爲它們只包含最小流程實例執行狀態對於一個簡單的過程實例,這通常包含一個或幾個節點的實例任何節點當前正在執行,並且可能的話,一些變量的值

安全點

一個流程實例狀態存儲流程引擎執行所謂的“安全點每當一個流程實例執行啓動或一個等待狀態延續發引擎的收益可以執行直到沒有更多的行動在這一點上,引擎已達到未來安全狀態堅持存儲過程實例狀態所有其他進程有可能受到影響實例

配置持久性

默認情況下,流程引擎保存運行時的數據持續然而,它可以通過非常簡單的配置做到這一點,通過添加一個配置文件和必要的依賴基於Java持久性APIJPA)的持久性本身,因此可以幾個持久性機制我們使用Hibernate在默認有情況下H2數據庫來存儲數據你可以選擇你自己選擇

首先,你需要添加必要的依存關係到你的classpath如果你使用Eclipse IDE你可以通過添加JAR文件到你的jBPM運行時目錄通過手動添加這些依賴關係到您的項目首先,你需要的JAR文件與jBPM持久化jpa.jar包含用於保存運行時的狀態必要時代碼接下來,您還需要其他各種依賴關係具體取決於您使用持久性解決方案和數據庫與Hibernate作爲JPA持久性提供程序H2數據庫和JTA的事務管理Bitronix默認組合下面的列表是需要額外的依賴

  • jbpm-persistence-jpa (org.jbpm)
  • drools-persistence-jpa (org.drools)
  • persistence-api (javax.persistence)
  • hibernate-entitymanager (org.hibernate)
  • hibernate-annotations (org.hibernate)
  • hibernate-commons-annotations (org.hibernate)
  • hibernate-core (org.hibernate)
  • dom4j (dom4j)
  • jta (javax.transaction)
  • btm (org.codehaus.btm)
  • javassist (javassist)
  • slf4j-api (org.slf4j)
  • slf4j-jdk14 (org.slf4j)
  • h2 (com.h2database)
  • commons-collections (commons-collections)

接下來,您需要配置jBPM引擎在必要時保存引擎狀態要做到這一點最簡單的方法使用JPAKnowledgeService創建您的知識會話基於知識基礎知識的會話配置(如有必要)和環境環境需要包含實體管理器工廠引用例如:

// create the entity manager factory and register it in the environment
EntityManagerFactory emf =
    Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa" );
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
 
// create a new knowledge session that uses JPA to store the runtime state
StatefulKnowledgeSession ksession =
    JPAKnowledgeService.newStatefulKnowledgeSession( kbase,null, env );
int sessionId = ksession.getId();
 
// invoke methods on your method here
ksession.startProcess( "MyProcess");
ksession.dispose();

您還可以YSEJPAKnowledgeService重新創建基於一個特定的會話ID會話

// recreate the session from database using the sessionId
ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( sessionId, kbase,null, env );

注意,我們只保存最小狀態,需要繼續在以後的某個執行過程實例這意味着例如,包含已經執行節點信息,如果該信息不再是相關的已完成或中止從數據庫中刪除該進程的實例。如果你想搜索歷史相關的信息應該使用的歷史記錄,後面會解釋

需要添加一個持久性配置到你的classpath配置JPA的使用HibernateH2數據庫(或您的偏好名爲persistence.xml的META - INF目錄,如下所示對於如何改變自己的配置更多細節,我們JPA和Hibernate文檔瞭解更多信息

<?xml version="1.0"encoding="UTF-8" standalone="yes"?>
<persistence
  version="1.0"
  xsi:schemaLocation=
    "http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
     http://java.sun.com/xml/ns/persistence/orm
     http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
 
  <persistence-unit name="org.jbpm.persistence.jpa">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/processInstanceDS</jta-data-source>
    <class>org.drools.persistence.info.SessionInfo</class>
    <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
    <class>org.drools.persistence.info.WorkItemInfo</class>
 
    <properties>
      <property name="hibernate.dialect"value="org.hibernate.dialect.H2Dialect"/>
      <property name="hibernate.max_fetch_depth"value="3"/>
      <property name="hibernate.hbm2ddl.auto"value="update"/>
      <property name="hibernate.show_sql"value="true"/>
      <property name="hibernate.transaction.manager_lookup_class"
                value="org.hibernate.transaction.BTMTransactionManagerLookup"/>
    </properties>
  </persistence-unit>
</persistence>

這個配置文件是指所謂的“JDBC /processInstanceDS數據源下面的Java代碼片段可以用來設置該數據源,在這裏我們使用的是基於文件的H2數據庫

PoolingDataSource ds = newPoolingDataSource();
ds.setUniqueName("jdbc/testDS1");
ds.setClassName("org.h2.jdbcx.JdbcDataSource");
ds.setMaxPoolSize(3);
ds.setAllowLocalTransactions(true);
ds.getDriverProperties().put("user","sa");
ds.getDriverProperties().put("password","sasa");
ds.getDriverProperties().put("URL","jdbc:h2:file:/NotBackedUp/data/process-instance-db");
ds.init();

如果你部署到應用服務器,通常可以deploy目錄中的配置文件例如,創建一個數據源

<?xml version="1.0"encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>jdbc/testDS1</jndi-name>
    <connection-url>jdbc:h2:file:/NotBackedUp/data/process-instance-db</connection-url>
    <driver-class>org.h2.jdbcx.JdbcDataSource</driver-class>
    <user-name>sa</user-name>
    <password>sasa</password>
  </local-tx-datasource>
</datasources>

2)轉換

只要你不提供您的應用程序事務邊界,發動機對發動機會自動執行一個單獨的事務每個方法調用如果這種行爲是可以接受的,你不需要做別的你可以,但是也可以指定自己事務邊界例如,這可以讓你組合成一個事務多個命令

您需要註冊後環境使用用戶定義事務之前事務管理器下面的代碼示例使用Bitronix事務管理接下來,我們使用Java事務APIJTA),指定事務邊界,如下圖所示

// create the entity manager factory and register it in the environment
EntityManagerFactory emf =
    Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa" );
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
env.set( EnvironmentName.TRANSACTION_MANAGER,
         TransactionManagerServices.getTransactionManager() );
 
// create a new knowledge session that uses JPA to store the runtime state
StatefulKnowledgeSession ksession =
    JPAKnowledgeService.newStatefulKnowledgeSession( kbase,null, env );
 
// start the transaction
UserTransaction ut =
  (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction" );
ut.begin();
 
// perform multiple commands inside one transaction
ksession.insert( newPerson( "John Doe" ) );
ksession.startProcess( "MyProcess");
 
// commit the transaction
ut.commit();

流程定義

流程定義文件通常被寫在一個XML格式這些文件可以很容易地存儲在文件系統在開發過程中但是,只要你想使知識在生產中一個或多個引擎訪問我們建議使用(邏輯)你的知識集中在一個或多個知識庫GuvnorDrools的一個項目,提供這一點它由一個倉庫用於存儲不同類型的知識不僅流程定義規則,對象模型它允許使用WebDAV知識運用知識代理當創建一個自動下載信息Guvnor便於檢索的知識基礎,提供了一個Web應用程序,允許業務用戶可以查看和更新知識信息信息如何做到這一點更多信息檢索的DroolsGuvnor文檔

歷史記錄

在許多情況下是非常有用如果沒有必要存儲流程實例的執行信息使這一信息可用於事後例如,爲了驗證一個特定的流程實例執行過什麼行動監測和分析一個特定的進程效率運行時數據庫存儲歷史信息通常不是一個好主意,因爲這將導致不斷增長運行數據監測和分析,查詢可能會影響運行時引擎性能這就是爲什麼歷史流程實例的執行信息是分開存儲

執行信息歷史記錄創建基於流程引擎在執行過程中生成的事件jBPM運行時引擎提供了一個通用機制,聽取各種不同的事件必要的信息可以很容易地這些事件提取持久化例如在數據庫中過濾器可用於存儲找到相關信息

存儲在數據庫中處理事件

jBPM的BAM模塊包含一個事件監聽器進程相關的信息存儲在一個數據庫直接使用JPA或Hibernate該數據庫包含兩個表,一個流程實例信息一個節點實例的信息見下圖

1.ProcessInstanceLog列出的過程實例ID進程(定義ID,開始日期和(如適用)所有流程實例結束日期

2.NodeInstanceLog此表包含哪些節點實際上每個流程實例執行更詳細的信息每當一個節點實例進入進來的連接通過傳出連接退出,這些信息是存儲在此表中對於這一點,存儲過程實例ID和正在執行流程實例進程ID節點實例ID和相應的節點ID節點實例中的問題在這個過程中定義最後,事件的類型0=輸入,1 =退出事件的日期以及存儲

日誌數據庫在這樣的歷史進程信息您需要註冊會話(或工作記憶記錄像這樣

StatefulKnowledgeSession ksession = ...;
JPAWorkingMemoryDbLogger logger = new JPAWorkingMemoryDbLogger(ksession);
 
// invoke methods one your session here
 
logger.dispose();

請注意,此記錄像其他任何審計記錄器這意味着你可以調用方法addFilter,以確保只有相關信息存儲在數據庫中添加一個或多個過濾只有所有過濾器接受信息會出現在數據庫中。它不再需要應將該記錄器

指定存儲信息數據庫修改的文件persistence.xml文件包括審計日誌以及ProcessInstanceLogNodeInstanceLogVariableInstanceLog,如下所示

<?xml version="1.0"encoding="UTF-8" standalone="yes"?>
<persistence
  version="1.0"
  xsi:schemaLocation=
    "http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
     http://java.sun.com/xml/ns/persistence/orm
     http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
 
  <persistence-unit name="org.jbpm.persistence.jpa">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/processInstanceDS</jta-data-source>
    <class>org.drools.persistence.info.SessionInfo</class>
    <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
    <class>org.drools.persistence.info.WorkItemInfo</class>
    <class>org.jbpm.process.audit.ProcessInstanceLog</class>
    <class>org.jbpm.process.audit.NodeInstanceLog</class>
    <class>org.jbpm.process.audit.VariableInstanceLog</class>
 
    <properties>
      <property name="hibernate.dialect"value="org.hibernate.dialect.H2Dialect"/>
      <property name="hibernate.max_fetch_depth"value="3"/>
      <property name="hibernate.hbm2ddl.auto"value="update"/>
      <property name="hibernate.show_sql"value="true"/>
      <property name="hibernate.transaction.manager_lookup_class"
                value="org.hibernate.transaction.BTMTransactionManagerLookup"/>
    </properties>
  </persistence-unit>
</persistence>

所有這些信息可以方便地查詢使用很多不同的使用情況創建一個特定的流程實例分析特定進程所有實例性能歷史記錄

只應考慮審計日誌的默認實現我們不知道你需要什麼樣的信息存儲進行分析之後由於性能原因,建議存儲有關數據根據你的用例可能會定義自己的數據模型用於存儲你需要的信息,並在使用過程中的事件監聽器來提取這些信息


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章