{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":" Custom extension ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"BPMN 2.0 Standards are a good thing for all parties ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Users don't have to worry about being tied to proprietary solutions provided by suppliers ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" frame , especially activiti Such an open source framework , It can provide the same function , Even better , Comparable to big suppliers ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" according to BPMN 2.0 standard , Move from big vendor solutions to activiti Just go through a simple and smooth process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"BPMN 2.0 The bad standard is ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" It's often the result of a lot of discussion and compromise between different companies ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Read the process definition as a developer BPMN 2.0xml when , Sometimes I feel it's too troublesome to do things with this structure and method ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" therefore activiti Make simplifying development a top priority , Using something called ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Activiti BPMN Expand ","attrs":{}},{"type":"text","text":" The function of , These extensions are new structures or methods to simplify the corresponding structures , Does not belong to BPMN 2.0 standard ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" according to BPMN 2.0 Notes on developing custom extensions for standards :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The premise of custom extension is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" There's always a simple way to turn it into a standard way .","attrs":{}},{"type":"text","text":" So when using custom extensions , You can undo the custom extension in time ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When using custom extensions ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", It's always clear that the new XML Elements , attribute ...","attrs":{}},{"type":"text","text":" Like using activiti: Namespace prefix ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The goal of the extension is to eventually add to the next version of BPMN standard , Or at least it can lead to a specific BPMN The discussion of structure ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":" event ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Events are used to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Show what's going on in the life cycle of the process .","attrs":{}},{"type":"text","text":" Events are always painted as ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" circle ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" stay BPMN 2.0 in , There are two categories of events :","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture (catching) event ","attrs":{}},{"type":"text","text":" or ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Trigger (throwing) event :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture (catching):","attrs":{}},{"type":"text","text":" When a process is executed to an event , Will wait to be triggered . The type of trigger is determined by the internal chart or XML Is determined by the type declaration in . Capture events and trigger events are distinguished in terms of display by whether the internal chart is filled ( white )","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Trigger (throwing):","attrs":{}},{"type":"text","text":" When a process is executed to an event , Will trigger an event . The type of trigger is determined by the internal chart or XML Is determined by the type declaration in . The display of trigger events and capture events is distinguished by whether the internal chart is filled ( black )","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Event definition ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Event definitions determine the semantics of events .","attrs":{}},{"type":"text","text":" If there is no event definition , Nothing special will be done in this event . A start event that does not have an event definition set does nothing when starting the process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If you add an event definition to the start event ( For example, timer event definition ) We declare the type of event that starts the process ( At this time, the timer event listener will be triggered at a certain time )","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Timer event definition ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Timer events are events triggered according to a specified time ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timer events can be used to start events , Intermediate events and boundary Events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Timer definition elements :","attrs":{}},{"type":"text","text":"==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timeDate:","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The time when the event was triggered .","attrs":{}},{"type":"text","text":" Use ISO8601 The format specifies a certain time :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"
\n 2011-03-11T12:13:14\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timeDuration:","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" How long to wait before specifying the timer .","attrs":{}},{"type":"text","text":" timeDuration It can be set to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timerEventDefinition","attrs":{}},{"type":"text","text":" Child elements , Use ISO8601 Prescribed format ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"
\n \n P10D\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timeCycle:","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Specify the interval between repetitions .","attrs":{}},{"type":"text","text":" Can be used to start process instances on a regular basis , Or send multiple reminders for timeout .timeCycle Elements can be in two formats :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ISO8601 Standard format ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"cron expression ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"
\n \n R3/PT10H\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Starting on the hour , Every time 5 Once per minute :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"0 0/5 * * * ?\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"== Be careful :==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The first number is seconds ,","attrs":{}},{"type":"text","text":" Not as usual Unix cron That means minutes ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Repeated time periods can deal with relative time better ,","attrs":{}},{"type":"text","text":" You can calculate some specific points in time : The start time of the user task ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"cron Expressions can handle absolute time ,","attrs":{}},{"type":"text","text":" This is particularly useful for timed start events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Use expressions in timer event definitions , The timer definition can be affected by process variables :","attrs":{}},{"type":"text","text":" The process definition must contain ISO8601( perhaps cron) Format string , To match the corresponding time type ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"
\n \n ${duration}\n \n \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Only enable job After the actuator , The timer will be triggered .","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"activiti.cfg.xml","attrs":{}},{"type":"text","text":" Medium ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"jobExecutorActivate","attrs":{}},{"type":"text","text":" I need to set to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"true,","attrs":{}},{"type":"text","text":" Default job The actuator is closed ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Error event definition ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" An error event is triggered by a specified error ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"BPMN Mistakes and Java It's totally different :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"BPMN Error events are designed to model business exceptions ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Java Exceptions are handled in a specific way ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The error event definition refers to a error Elements , Same reference error The error event handler of the element will catch this error ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"
\n \n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Signal event definition ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The signal event refers to a named signal ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Signal global events ( Broadcast semantics ). Will be sent to all active processors ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Signal event definition uses ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":".signalRef","attrs":{}},{"type":"text","text":" Properties refer to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"definitions","attrs":{}},{"type":"text","text":" Defined in the root node ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signal","attrs":{}},{"type":"text","text":" Subelement (signalEventDefinition Quote the same signal Elements )","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n
\n \n \n\n \n \n \n \n \n ...\n \n \n \n \n ...\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Trigger signal events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Can pass bpmn The node triggers a signal by the process instance . It can also be done through API Trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"org.activiti.engine.RuntimeService","attrs":{}},{"type":"text","text":" The method in can be used to manually trigger a signal :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"RuntimeService.signalEventReceived(String signalName);\nRuntimeService.signalEventReceived(String signalName, String executionId);\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventReceived(String signalName):","attrs":{}},{"type":"text","text":" Send the signal to all global subscription processing ( Broadcast semantics )","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventReceived(String signalName, String executionId):","attrs":{}},{"type":"text","text":" Send the signal to the designated execution ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Capture signal events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Signal events can be captured by intermediate signal events or boundary information events ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Query the subscription of signal events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Query the execution of all subscription specific signaling events ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":" List executions = runtimeService.createExecutionQuery()\n .signalEventSubscriptionName(\"alert\")\n .list();\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventReceived(String signalName, String executionId)","attrs":{}},{"type":"text","text":" Send the signal to these executors ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Signal event range ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" By default , The signal is broadcast within the scope of the process engine :","attrs":{}},{"type":"text","text":" Throw a signal event in a process instance , Other process instances of different process definitions can listen to this event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Sometimes just respond to this signal event in the same process instance : Synchronization mechanism in process instances , If two or more activities are mutually exclusive ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" To limit the range of signal events ,","attrs":{}},{"type":"text","text":" You can use signal events to define ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"scope","attrs":{}},{"type":"text","text":" attribute :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" By default ,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"scope","attrs":{}},{"type":"text","text":" The property of is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"global","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Signal event examples ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Different processes use signal interaction :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The process starts when insurance rules are updated or changed . When modifications are processed by participants , Will trigger a signal , Notice of rule change :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b8/b845121391a67ee466a20a20f210b0be.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" This event is captured by all related process instances ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Subscribe to the process instance of this event :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/06/06621e8ff26af398d363e0283453aba5.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Signal events are broadcast to all active processors ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the example above , All process instances receive this event , That's what we want .","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" However , In some cases, you don't want this kind of broadcasting behavior , Consider the following process :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9d/9d7a7ce5f2df4be59838afb6fb3e0c86.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The model described in the above process activiti Does not support . The idea is :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" perform [do something] Errors in the task ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Caught by boundary error events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then use the signal to propagate to the branches on the concurrent path ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And then interrupt [do something inparallel] Mission ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" at present ,activiti The result of actual operation is consistent with the expectation . The signal propagates to the boundary event and interrupts the mission . however , According to the broadcast meaning of the signal , It is also propagated to all other process instances that subscribe to signaling events . therefore , That's not what we want ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Signaling events do not perform any connection to a specific process instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If you only want to send one message to the specified process instance , You need to manually associate , Reuse ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventReceived(String signalName, String executionId)","attrs":{}},{"type":"text","text":" And corresponding ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Query mechanism ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Message event definition ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Message events refer to a named message , Every message has a name and content ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Message events are always sent directly to a recipient ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Message event definitions use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"messageEventDefinition","attrs":{}},{"type":"text","text":" Elements .","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"messageRef","attrs":{}},{"type":"text","text":" Property references ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"definitions","attrs":{}},{"type":"text","text":" One under the root node ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"message","attrs":{}},{"type":"text","text":" Subelement :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n\n\n \n \n\n \n\n \n \n \n ...\n \n \n \n ...\n \n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Trigger message events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" As an embedded process engine ,activiti Can't actually receive a message ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" These are environment related , Platform related activities : Like connecting to JMS(Java Message service ) Queue or topic or execution ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"WebService or REST request .","attrs":{}},{"type":"text","text":" This message is received at the application or architecture level , The process engine is embedded in it ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" After the application receives a message , It has to be decided how to deal with it :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the message should trigger the start of a new process instance , In the following ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"RuntimeService","attrs":{}},{"type":"text","text":" Select one of the two methods to execute :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"ProcessInstance startProcessInstanceByMessage(String messageName);\nProcessInstance startProcessInstanceByMessage(String messageName, Map processVariables);\nProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map processVariables); \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" These methods allow the use of corresponding message system process instances ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the message needs to be processed by a running process instance :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" First, find the corresponding process instance according to the message ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then trigger the waiting process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"RuntimeService","attrs":{}},{"type":"text","text":" A subscription based on message events is provided to trigger the process to continue execution :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"void messageEventReceived(String messageName, String executionId);\nvoid messageEventReceived(String messageName, String executionId, HashMap processVariables); \n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Query message event subscription ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Activiti Support ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Start message event ","attrs":{}},{"type":"text","text":" and ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate message events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Message start event :","attrs":{}},{"type":"text","text":" A message event subscription is assigned to a specific ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"process definition.","attrs":{}},{"type":"text","text":" This message subscription can use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ProcessDefinitionQuery","attrs":{}},{"type":"text","text":" Query to ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()\n .messageEventSubscription(\"newCallCenterBooking\")\n .singleResult();\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Because only one process definition can be associated with the subscription point of the message at the same time , Queries always return 0 Or a result . If the process definition is updated , Only the latest version of the process definition will subscribe to the message event ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture message events :","attrs":{}},{"type":"text","text":" Message event subscriptions are assigned to specific execution , This message event subscription can use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ExecutionQuery","attrs":{}},{"type":"text","text":" Query to :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"Execution execution = runtimeService.createExecutionQuery()\n .messageEventSubscriptionName(\"paymentReceived\")\n .variableValueEquals(\"orderId\", message.getOrderId())\n .singleResult();\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" This query can call the corresponding query , It's usually process related information ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":": There can only be at most one process instance corresponding to orderId","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Message event instance ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Process instances started with two different messages :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b6/b6df6590cb4dcd818722c1ffa6189e71.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Message events can be used when processes need different ways to distinguish start events , It's going to end up in the same path ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Start the event ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The start event is used to indicate where the process starts ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The type of start event ( The process starts when it receives the event , Or start at a specified time ...),","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Defines how the process starts ,","attrs":{}},{"type":"text","text":" This is shown by the different little charts in the event . stay XML in , These types are distinguished by declaring different child elements ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Start events are capture events :","attrs":{}},{"type":"text","text":" In the end, these events have been waiting for , Until the corresponding ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" trigger ","attrs":{}},{"type":"text","text":" appear ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the beginning of the event , You can set activiti Specific properties :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"initiator:","attrs":{}},{"type":"text","text":" When the process starts , Save the current login user to the specified variable name :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The logged in user must use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"IdentityService.setAuthenticatedUserId(String)","attrs":{}},{"type":"text","text":" Method setting , And included in ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"try-finally","attrs":{}},{"type":"text","text":" In the code :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":" try {\n identityService.setAuthenticatedUserId(\"bono\");\n runtimeService.startProcessInstanceByKey(\"someProcessKey\");\n} finally {\n identityService.setAuthenticatedUserId(null);\n}\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Empty start event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The null start event technically means that there is no trigger condition specified to start the process instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The engine can't predict when the process instance will start ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The null start event is used for :","attrs":{}},{"type":"text","text":" When a process instance is to pass API Start the scene , By calling ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"startProcessInstanceByXXX","attrs":{}},{"type":"text","text":" Method ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Each subprocess has an empty start event ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The empty start event is shown as a circle . No internal charts , That is, there is no trigger type ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bc/bcb7cfec8a17bfa405a426019a2aa85a.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML structure ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Empty start event XML Structure is a common start event definition ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", There are no child elements ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Other start event types have a child element to declare their own type ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Custom extension of null start event ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"formKey:","attrs":{}},{"type":"text","text":" Refer to the form template that users need to fill in when starting a new process instance ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Start the event regularly ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The timed start event is used to create a process instance at a specified time :","attrs":{}},{"type":"text","text":" It can be used for processes that are started only once and processes that should be started multiple times at a specific time interval ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"== Be careful :==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Subprocesses cannot use timed start events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The timed start event starts to calculate the time after the process is released ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" No call required startProcessInstanceByXXX,","attrs":{}},{"type":"text","text":" Although you can also call the method that starts the process , But that leads to calling startProcessInstanceByXXX Start too many processes when ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" When a new version of the process that contains timed start events is deployed , The corresponding last timer will be deleted .","attrs":{}},{"type":"text","text":" This is because you usually don't want to automatically start process instances of older versions of processes ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The timing start event is shown as a circle , Inside is a table :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b330ce137f9da4f825976aac247973dd.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Start the event regularly XML The content is a statement of a normal start event **, Contains a timing definition sub element **","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n \n \n R4/2011-03-11T12:13/PT5M\n \n \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n \n \n 2011-03-11T12:13:14\n \n \n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Message start event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The message start event can start a process instance with a named message , This allows you to use the message name to select the correct start event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" When publishing a process definition that contains one or more message start events :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The name of the message start event cannot be duplicated in the given process definition :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" A process definition cannot contain more than one message start event with the same name ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If two or more message start events apply the same event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Or two or more message events refer to the same message name ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"activiti Will be in ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Exception thrown when publishing process definition ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The name of the message start event cannot be repeated in all published process definitions :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If one or more message start events refer to messages of the same name ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And this message start event has been deployed into different process definitions ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"activiti will ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Throw an exception at publish time ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" When releasing a new version of the process definition , The previous subscription will be cancelled :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If there is no message in the new version, the event will be handled like this ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Start process instance , The message start event can use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"RuntimeService","attrs":{}},{"type":"text","text":" To trigger :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"ProcessInstance startProcessInstanceByMessage(String messageName);\nProcessInstance startProcessInstanceByMessage(String messageName, Map processVariables);\nProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map\n\n \n\n \n\n \n \n \n ...\n \n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Signal start event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The signal start event can be passed through a named signal (signal) To start a process instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Signals can be used inside process instances ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate signals throw transactions ","attrs":{}},{"type":"text","text":" Trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" It can also be done through API(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"runtimService.signalEventReceivedXXX","attrs":{}},{"type":"text","text":") Trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In both cases , In all process instances ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" With the same name signalStartEvent Will start ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In both cases , You can choose ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Synchronous or asynchronous ","attrs":{}},{"type":"text","text":" Start the process instance in the same way ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You have to go to API Pass in ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalName,","attrs":{}},{"type":"text","text":" This is a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signal","attrs":{}},{"type":"text","text":" Elemental ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"name","attrs":{}},{"type":"text","text":" Property value , It will be ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventDefinition","attrs":{}},{"type":"text","text":" Of ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalRef","attrs":{}},{"type":"text","text":" Property reference ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The signal start event is displayed as a circle with a signal event icon in the middle . The tag is unfilled , To capture ( receive ) Behavior ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/83/83645a7046195fb0d1af447e5e5e06b9.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Format ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalStartEvent","attrs":{}},{"type":"text","text":" Of XML The format is standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"startEvent","attrs":{}},{"type":"text","text":" Statement , There is one ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventDefinition","attrs":{}},{"type":"text","text":" Subelement ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n\n \n \n \n \n \n \n \n \n \n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Error start event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The error start event can be used to trigger an event subprocess . Error start events cannot be used to start process instances ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Error start events are ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Interruptions ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The error start event is a circle , Contains an error event tag . The mark is white and unfilled , To represent capture ( receive ) Behavior ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/78/7889b4df5b00a2068997056cd796de01.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Error start event XML The content is in the normal start event definition , Contains a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"errorEventDefinition","attrs":{}},{"type":"text","text":" Subelement ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" End the event ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The end event indicates ( Son ) technological process ( Branch ) The end of ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The ending events are all ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Triggering event :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The process reaches the end event , It triggers an outcome ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The type of result is through the inside of the event ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Black Icon ","attrs":{}},{"type":"text","text":" It means ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" stay XML In content , Declared by containing child elements ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Empty end event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" A null end event means that the result thrown is not specified when the event arrives ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The engine will end the current branch directly , Not doing anything else ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The null end event is a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Thick edged circle ,","attrs":{}},{"type":"text","text":" There are no small icons inside ( No result type )","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/68/680478c594c7ee56021c1067b3c51e1f.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Empty end event XML The content is the general end event definition ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Does not contain child elements , All other end event types contain child elements of the declaration type ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Error end event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the process is executed to the wrong end event ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", The current branch of the process ends , And throw an error ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" This error can be caught by the corresponding intermediate boundary error event . If no matching boundary error event is found , Will throw an exception ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The error end event is a standard end event ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"- Thick edged circle ,","attrs":{}},{"type":"text","text":" Internal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Error Icon ,","attrs":{}},{"type":"text","text":" The error icon is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" All black , Represents the trigger syntax ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c8/c827f3f826b7df9f6543ec52d83ad002.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The content of the error end event is a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Error events ,","attrs":{}},{"type":"text","text":" The child element is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"errorEventDefinition","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"errorRef Property references are defined outside the process error Elements :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n...\n\n...\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"error Of errorCode Used to find ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Matching capture boundary error events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If errorRef With any error None of them match , will ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Use errorRef As a errorCode Abbreviation .","attrs":{}},{"type":"text","text":" This is a activiti Specific abbreviations :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n...\n\n...\n \n \n \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Equate to ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful errorRef Must be with BPMN 2.0 The format matches , It has to be a legal QName","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Cancel the end event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Canceling an end event can only be associated with BPMN Combined use of transaction subprocesses ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the cancellation end event is reached , Will throw a cancel event ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", It has to be captured by the cancel boundary event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Canceling the boundary event cancels the transaction , And trigger the compensation mechanism ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Cancel end events are displayed as standard end Events - Thick edged circle , Contains a cancel icon . The cancel icon is all black , Represents the trigger syntax ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8d/8d27061e7041b0ccd4fc4a85df6f1aed.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Canceling the end event content is a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" End the event ,","attrs":{}},{"type":"text","text":" contain ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"cancelEventDefinition","attrs":{}},{"type":"text","text":" Subelement ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Boundary event ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Boundary events are capture events , It will be attached to a link ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary events are capture events , It's impossible to trigger events :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the node is running , Events listen for the corresponding trigger type ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When events are captured , The node will break , At the same time, execute the subsequent connection of the event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary events are defined in the same way :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary events are defined as follows :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Unique identification : The scope of the process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Use caught Property refers to the node of the event , Note that boundary events are at the same level as the nodes they attach : such as , Boundary events are not contained within nodes ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The format is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"XXXEventDefinition","attrs":{}},{"type":"text","text":" Of XML Subelement ( such as ,TimerEventDefinition,ErrorEventDefinition...) The definition of boundary events ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" type ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Timed boundary Events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" A timed boundary event is a clock that pauses waiting for a warning ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the process is executed to a link bound with boundary Events , Will start a timer ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the timer is triggered ( Within a certain period of time ), The link will be interrupted , And continue to execute along the outgoing line of the timing boundary event ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timed boundary events are a standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary event ","attrs":{}},{"type":"text","text":"( A circle on the border ), Inside is a little timer icon ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/02/0215ff226bcdc71aa6187fb0315c5107.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timer boundary task definition is a standard boundary event , The child element of the specified type is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timerEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n PT4H\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the flow chart , The edge of the circle is a dotted line :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/af/af4608154b46f4a399cf901137847227.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Classic application scenarios :","attrs":{}},{"type":"text","text":" Send a notification email , But don't interrupt the normal process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" There is a difference between interrupted and non interrupted events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The default is interrupt events ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the case of non interruptive Events , It doesn't interrupt the original link , That link is still in place ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Corresponding , A new branch will be created , And follow the flow of events . stay XML In content , To put ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"cancelActivity","attrs":{}},{"type":"text","text":" Property is set to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"false","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"== Boundary timing events can only occur in ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"job When the actuator is enabled ","attrs":{}},{"type":"text","text":" Use ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" such as : hold ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"activiti.cfg.xml","attrs":{}},{"type":"text","text":" Medium ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"jobExecutorActivate","attrs":{}},{"type":"text","text":" Set to true, Default job The actuator is disabled ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" The issue of boundary Events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Synchronization problem :","attrs":{}},{"type":"text","text":" There can't be more than one outgoing connection behind a boundary event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The solution to this problem is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Using concurrent gateways after a connection ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2e/2e69f2c42357c1b2acfeba51cc094b82.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Error boundary event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Error boundary event :","attrs":{}},{"type":"text","text":" Intermediate catch error events on node boundaries , Will catch errors thrown within the scope of the node ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Define a boundary error event , Mostly for ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Embedded subprocesses ","attrs":{}},{"type":"text","text":" perhaps ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Call node ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the case of subprocesses , It creates a scope for all internal nodes ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" An error is thrown by an error end event . This error is passed to the upper scope , Until a boundary error event is found that matches the error event definition ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When an error event is caught ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", The node bound to the boundary task is destroyed , It will also destroy all internal executive branches ","attrs":{}},{"type":"text","text":"( Synchronization node , Embedded subprocesses ...). Process execution will continue ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Continue along the outgoing line of the boundary event ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The error boundary event appears as a normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( There is a small circle inside the circle ) Put it on the label of the node , There is a small error icon inside . The error icon is white , Indicates that it is a capture event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/64/646ce115c410972ffd40afaaa092dea9.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Boundary error events are defined as ordinary boundary events :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Like the error end event ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":",errorRef","attrs":{}},{"type":"text","text":" Refer to the ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"process","attrs":{}},{"type":"text","text":" An incorrect definition outside the element ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n...\n\n...\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"errorCode","attrs":{}},{"type":"text","text":" Used to match captured errors :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" If not set errorRef, Boundary error events capture all error events , Whatever is wrong errorCode What is it? ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" If set errorRef, And quoted an existing error , The boundary event just catches the same error code ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" If set errorRef, however BPMN 2.0 There is no definition error in ,errorRef It's like errorCode Use ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Error boundary event instance ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" How to use the process instance of the error end event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the user task of auditing profit is completed , If you don't provide enough information , Will throw an error ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Errors are caught by the boundary tasks of the subprocess , All nodes in the review sales subprocess are destroyed , Even if the audit of the customer ratio has not been completed , And create a user task that provides more information ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/84/847aa5e8acaed7a01d12167949be0243.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Signal boundary event ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The middle of the node boundary ","attrs":{}},{"type":"text","text":" Capture signal , A signal with the same signal name referenced by the signal definition is captured ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And other events ( Like boundary error events ) Different , Boundary signal events are not just ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture ","attrs":{}},{"type":"text","text":" Bind the azimuth signal . Signal events are a global scope ( Broadcast semantics ), That is to say ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The signal can be triggered anywhere , Even different process instances ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And other events ( Like boundary error events ) Different ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":", After capturing the signal , It doesn't stop the signal .","attrs":{}},{"type":"text","text":" If there are two signal boundary Events ,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture the same signal events , Both boundary events are triggered , Even in different process instances ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Boundary signal events are shown as normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( There's a little circle in the circle ), Position in ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The edge of the node ,","attrs":{}},{"type":"text","text":" There's a little signal icon inside . The signal icon is white ( Unfilled ), Meaning capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/93/93fe70e6a27f1c2e5e10f0f69988e207.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Boundary signal events are defined as ordinary ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary event :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Message boundary Events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The middle of the node boundary ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture the message ,","attrs":{}},{"type":"text","text":" According to the referenced message definition ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Capture messages with the same message name ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The boundary message event appears as a normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( There's a little circle in the circle ), At the edge of the node , Inside is a small message icon . The message icon is white ( No filling ), Meaning capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3d/3db333372d96de53125761987c3fd6ee.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"== The boundary message event may be ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Non interruptive ( left )","attrs":{}},{"type":"text","text":" perhaps ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" interrupt ( On the right side )","attrs":{}},{"type":"text","text":" Of ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Boundary message events are defined as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary event ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Cancel border Events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture cancellation at the boundary of a transactional subprocess ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Triggered when the transaction is cancelled , When the cancel boundary event is triggered :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" First, interrupt all execution of the current scope ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then start to compensate all active compensation boundary events in the transaction . Compensation is performed synchronously : Before leaving the business , The boundary transaction will wait for the compensation to complete ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the compensation is completed , The transaction subprocess will continue along the outgoing line of canceling the boundary transaction ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Each transaction subprocess can only have one cancel boundary event ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" If a transaction subprocess contains an embedded subprocess , Compensation only triggers a sub process that has been successfully completed ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" If the transaction subprocess corresponding to the cancel boundary subprocess is configured as multi instance , If an instance triggers cancellation , Will cancel all instances ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The cancel boundary event is displayed as a normal intermediate event ( A small circle in a circle ), At the edge of the node , Inside is a small cancel icon . The cancel icon is white ( No filling ), It means capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4d/4d5c76be205f26e53c418e282dfbfa8b.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The cancel boundary event is defined as normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Boundary event ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Canceling boundary events is interrupted , No need to use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"cancelActivity","attrs":{}},{"type":"text","text":" attribute ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Compensation for boundary Events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture compensation of node boundary ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The compensation processor used to set up a node ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation boundary events must use ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Direct reference ","attrs":{}},{"type":"text","text":" Set up a unique compensation processor ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The strategy of compensating boundary events is different from other boundary events :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Other border Events ( Signal boundary event ) When it reaches the associated node, it is activated . When leaving the node , Will hang up , The corresponding event subscription will also be cancelled ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The compensation boundary event is activated when the associated node completes successfully , When the compensation event triggers or the corresponding process instance ends , Event subscription will be deleted ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Compensation boundary events follow the following rules :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When compensation is triggered , The compensation processor corresponding to the compensation boundary event will call the same number of times , According to the number of successes of its corresponding node ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the compensation boundary event is associated with a multi instance node , Compensation events subscribe to each instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the node associated with the compensation boundary event contains a loop , Compensation events are subscribed every time the node executes ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the process instance ends , The compensation event of the subscription will end ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Compensation boundary events do not support embedded subprocesses ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation boundary events are shown as standard intermediate Events ( A circle in a circle ), At the edge of the node , There's a little compensation icon inside . The compensation icon is white ( No filling ), Meaning capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The following illustration shows using undirected associations , Set compensation processor for boundary Events :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/97/97d9524e9b594497f74f377fbaed2b18.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation boundary events are defined as ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Standard boundary Events ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n\n\n\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation for boundary Events ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Activate after the node completes successfully ,","attrs":{}},{"type":"text","text":" I won't support it ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"cancelActivity","attrs":{}},{"type":"text","text":" attribute ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Intermediate capture events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" All intermediate capture events are defined in the same way :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Definition of intermediate capture events :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Unique identification ( Within the scope of the process )","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" One structure is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"XXXEventDefinition","attrs":{}},{"type":"text","text":" Of XML Subelement (TimerEventDefinition) Defines the types of intermediate capture events ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Timing intermediate capture events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timed intermediate event as a ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Monitor ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When the execution reaches the capture event node , Will start a timer . When the timer triggers ( such as , After a while ), The process will continue along the outgoing node of the timed intermediate event ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timer intermediate events are displayed as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture events ,","attrs":{}},{"type":"text","text":" Inside is a little timer icon :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f4/f4b166a0df9f4e8a32dada177a7a4ea0.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Timer intermediate events are defined as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture events .","attrs":{}},{"type":"text","text":" The child elements of the specified type are ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"timerEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":" \n \n PT5M\n \n \n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Capture events in the middle of the signal ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Intermediate capture signal events , adopt ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Reference signal definition to capture signals with the same signal name ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Signals capture events in the middle and other events ( Like error events ) Different :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Signals are not consumed after they are captured ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If there are two active signal boundary events that capture the same signal event , Both boundary events are triggered , Even in different process instances ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The intermediate signal capture event is shown as a normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( A circle is a circle ), There's a little signal icon inside . The signal icon is white ( No filling ), Meaning capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c0/c0ee34b3f23dac0e2166c2dcffd443e3.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Signal intermediate events are defined as ordinary ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture events .","attrs":{}},{"type":"text","text":" The child element of the corresponding type is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Capture events in the middle of a message ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Intermediate capture message events , Capture a message with a specific name ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Intermediate capture message events are shown as normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( A circle is a circle ), Inside is a small message icon . The message icon is white ( No filling ), Meaning capture ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/05/05c481f3a854781cc1755d6b560d8d94.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Message intermediate events are defined as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate capture events .","attrs":{}},{"type":"text","text":" The child element of the specified type is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"messageEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Internal trigger events ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The definition of all internal triggering events is the same :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The internal trigger event definition contains :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Unique identification ( The scope of the process )","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Use format as ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"XXXEventDefinition","attrs":{}},{"type":"text","text":" Of XML Subelement ( such as signalEventDefinition etc. ) Define the type of intermediate trigger event ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Empty events are triggered in the middle ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Air to air triggering event flow chart , Used to represent a state in a process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7c/7c9537124afa9af4ad3dc4c39faec3aa.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Sure ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Add an execution listener :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n \n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You can add your own code , Send the event to BAM Tools or DWH. The engine won't do anything for this event , It goes straight through ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Trigger events in the middle of the signal ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Trigger events in the middle of the signal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Throw a signal event for the defined signal ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" stay activiti in , Signal meeting ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" radio broadcast ","attrs":{}},{"type":"text","text":" To all active processors . The signal can ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Publish both synchronously and asynchronously ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Under default configuration , The signal is sent synchronously :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The process instance that throws the event will wait until the signal is sent to all capture process instances to continue execution ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Capturing process instances is also executed in the same transaction that triggers the process instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If there is a technical problem with a monitoring process ( Throw an exception ), All related instances fail ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Signals can also be sent asynchronously :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" After reaching the throw signal event, it determines which processors are active ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" For these activated processors , An asynchronous reminder message is saved ( Mission ), And send it to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"jobExecutor","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The intermediate signal trigger event is displayed as normal ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( A circle is a circle ), Another small signal icon inside , The signal icon is black ( There's padding ), It means to trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bc/bc41b1d68db6af8c3b57d57285052cfa.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Message intermediate events are defined as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate trigger events .","attrs":{}},{"type":"text","text":" The child element of the specified type is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"signalEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Asynchronous signal events are as follows :","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Compensate for intermediate trigger events ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" describe ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Used to trigger compensation ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Trigger compensation :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation can be made by ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" A specific node or scope that contains compensation events ","attrs":{}},{"type":"text","text":" Trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation is allocated to ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The compensation processor of the node ","attrs":{}},{"type":"text","text":" To complete ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When compensation is triggered by nodes , The corresponding compensation processor will execute the same number of times according to the number of successful completion of the node ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If compensation is triggered by the current scope , All nodes in the current scope perform compensation , It also includes concurrent branches ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The trigger of compensation is inherited :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":3,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the node performing compensation is a sub process , Compensation will affect all nodes included in the subprocess ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":3,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the subprocess is an embedded node , Compensation triggers recursively ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":3,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation doesn't spread to the top of the process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":3,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If compensation is triggered in a subprocess , It doesn't propagate outside the scope of the subprocess ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":3,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"bpmn Specification definition , The process triggered by the node will only affect the same level of the sub process ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"activiti The order of compensation execution is opposite to that of process execution :","attrs":{}},{"type":"text","text":" The last completed node performs compensation first ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation intermediate trigger events can be used to compensate for successful completion of transactional subprocesses ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"==","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Be careful :","attrs":{}},{"type":"text","text":"==","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If compensation is triggered by a scope that contains subprocesses , The subprocess also contains nodes associated with the compensation processor , If it's done successfully , Compensation only propagates to subprocesses ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" If the nodes in the subprocess are also completed , And associated with the compensation processor , If the nodes contained in the subprocess have not been completed , The compensation processor is not executed ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/53/5378e72d6c0b0d2e579edfcfb99a52fb.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In this process , We have two concurrent branches , One branch is the embedded subprocess , One is to use the credit card node . Suppose both branches are started , The first branch waits for the user to complete the audit scheduled task . The second branch is executed using the credit card node , And a mistake happened , This leads to a cancellation event , And trigger compensation . At this time , The merge sub process is not over yet , This means that the compensation event does not propagate to the subprocess , So cancellation of hotel reservation is not executed by the compensation processor . If the user task ( It's embedded subprocesses ) It was done before the cancellation , Compensation is propagated to the embedded subprocess ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Process variables :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When compensating for embedded subprocesses , The branch used to execute the compensation processor can access the local process instance of the subprocess , Because this is the branch of the subprocess ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In order to achieve this function , Snapshots of process variables are assigned to branches ( Branches created to execute subprocesses ) There are the following restrictions :","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The compensation processor cannot access the , Variables added to the synchronization Branch ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" The process variables assigned to the branch are at the top of the inheritance relationship ","attrs":{}},{"type":"text","text":"( The process variables assigned to the process instance are not included in the snapshot ): When compensation is triggered , Compensation processors access these process variables from where they are ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Variable snapshots are only used to embed subprocesses , Not applicable to other nodes ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" Known limitations :\n 1. waitForCompletion=\"false\" Not yet . When compensation is triggered by an intermediate trigger compensation event , The event did not wait , After the successful completion of compensation \n 2. Compensation itself is performed by concurrent branches . The execution order of concurrent branches is opposite to the completion order of compensated nodes . future activiti Options may be supported to perform compensation sequentially \n 3. Compensation will not spread to callActivity Called subprocess instance \n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":" Graphic markers ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Intermediate compensation trigger events are displayed as standard ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate Events ","attrs":{}},{"type":"text","text":"( A circle is a circle ), Inside is a little compensation icon . The compensation icon is black ( There's padding ), It means to trigger ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/15/15c8af9a4014ee0d146be6840cdc7a9a.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"XML Content ","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compensation intermediate events are defined as ordinary ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Intermediate trigger events .","attrs":{}},{"type":"text","text":" The child element of the corresponding type is ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"compensateEventDefinition","attrs":{}},{"type":"text","text":" Elements ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Optional parameters ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"activityRef","attrs":{}},{"type":"text","text":" Can be used to trigger specific scopes / Node compensation ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"xml"},"content":[{"type":"text","text":"\n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}