<start >
<transition to="fork"/>
</start>
<fork >
<on event="end" continue="exclusive" />
<transition />
<transition />
</fork>
<java class="org.jbpm.examples.async.fork.Application" >
<transition />
</java>
<java class="org.jbpm.examples.async.fork.Application" >
<transition />
</java>
<join >
<transition to="end"/>
</join>
<end />
</process>public class Application {
public void shipGoods() {
// assume automatic calculations here
}
public void sendBill() {
// assume automatic calculations here
}
}通過在fork的end事件上使用異步調(diào)用 (<on event="end" continue="exclusive" />), 每個沿著分支轉(zhuǎn)移生成的執(zhí)行都會 使用異步方式繼續(xù)執(zhí)行。
exclusive這個值被用來 將兩個來自分支的異步調(diào)用的job結(jié)果進(jìn)行持久化。 各自的事務(wù)會分別執(zhí)行ship goods和send bill, 然后這兩個執(zhí)行都會達(dá)到j(luò)oin節(jié)點。 在join節(jié)點中,兩個事務(wù)會同步到一
個相同的執(zhí)行上(在數(shù)據(jù)庫總更新同一個執(zhí)行), 這可能導(dǎo)致一個潛在的樂觀鎖失敗。
ProcessInstance processInstance = executionService.startProcessInstanceByKey("AsyncFork");
String processInstanceId = processInstance.getId();
List<Job> jobs = managementService.createJobQuery()
.processInstanceId(processInstanceId)
.list();
assertEquals(2, jobs.size());
Job job = jobs.get(0);
// here we simulate execution of the job,
// which is normally done by the job executor
managementService.executeJob(job.getDbid());
job = jobs.get(1);
// here we simulate execution of the job,
// which is normally done by the job executor
managementService.executeJob(job.getDbid());
Date endTime = historyService
.createHistoryProcessInstanceQuery()
.processInstanceId(processInstance.getId())
.uniqueResult()
.getEndTime();
assertNotNull(endTime);6.7. 用戶代碼
jPDL流程語言中的大量元素都引用一個對象, 它的一個接口方法將被調(diào)用。這一章介紹了通用屬性和元素, 對這些用戶編碼對象 進(jìn)行初始化和配置。
custom
event-listener
task中的assignment-handler
decision中的handler
transition中的condition
6.7.1. 用戶代碼配置
表 6.38. 屬性:
屬性 類型 默認(rèn)值 是否必填? 描述
class 類名 {class|expr}其中之一是必須的 全類名。初始化只會進(jìn)行一次, 用戶對象會被作為流程定義的一部分進(jìn)行緩存。
expr 表達(dá)式 {class|expr}其中之一是必須的 表達(dá)式的值會當(dāng)做目標(biāo)對象被獲得。 表達(dá)式會在每次使用時被執(zhí)行。換句話說, 執(zhí)行的結(jié)果值不會被緩存。
表 6.39. 用戶代碼配置元素:
元素 數(shù)目 描述
field 0..* 描述一個配置值,在用戶類使用之前 注入到成員變量中。
property 0..* 描述一個配置值,在用戶類使用之前 通過一個setter方法進(jìn)行注入。
表 6.40. field 和 property 的屬性:
屬性 類型 默認(rèn)值 是否必填? 描述
name string 必填 field或property的名稱。
表 6.41. field 和 property 包含的元素:
field 和 property 元素 都擁有一個子元素, 表示將被注入的值。
元素 數(shù)目 描述
string 0..1 a java.lang.String
int 0..1 a java.lang.Integer
long 0..1 a java.lang.Long
float 0..1 a java.lang.Float
double 0..1 a java.lang.Double
true 0..1 Boolean.TRUE
false 0..1 Boolean.FALSE
object 0..1 會通過反射初始化的對象
表 6.42. 基本類型 string, int, long, floatand double的屬性:
屬性 類型 默認(rèn)值 是否必填? 描述
value text 必填 text值會被解析成期望的類型
6.7.2. 用戶代碼類加載器
流程定義被緩存了。默認(rèn)情況,所有用戶代碼對象 都會作為流程定義的一部分被緩存。 對于所有通過類名引用的對象, 都會在解析期間被初始化。這就意味著,這些對象 不允許保存非無狀態(tài)化的數(shù)
據(jù)(比如可以改變)。 實際上因為這些對象實際都常常是不會改變的。 如果你需要使用“動態(tài)”數(shù)據(jù)在你的用戶代碼中,你通??梢?使用流程變量(或調(diào)用Environment.get(xxx))。
表達(dá)式中引用的對象 是動態(tài)計算的。
開發(fā)只能拿也解釋了未支持的屬性, 來預(yù)防用戶對象的緩存