如何解决Activiti > 5.17 违反参照完整性约束:在完成任务之前添加本地任务变量时出现“ACT_FK_VAR_EXE”
请看下图
MyProcess.bpmn
<?xml version="1.0" encoding="UTF-8"?>
<deFinitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="evl" name="Evaluation"></userTask>
<boundaryEvent id="timer_event_autocomplete" name="Timer" attachedToRef="evl" cancelActivity="false">
<timerEventDeFinition>
<timeDate>PT2S</timeDate>
</timerEventDeFinition>
</boundaryEvent>
<serviceTask id="timer_service" name="Timed Autocomplete" activiti:async="true" activiti:class="com.example.service.TimerService"></serviceTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="evl"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="timer_event_autocomplete" targetRef="timer_service"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="evl" targetRef="endevent1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
</process>
</deFinitions>
用文字来描述它,有一个用户任务(评估)和一个附加到它的计时器(配置为在 2 秒内触发)。触发计时器后,其 Java 委托 TimerService 中的定时自动完成异步服务任务尝试完成用户任务(评估),流程结束。
TimerService.java
public class TimerService implements JavaDelegate {
Logger LOGGER = LoggerFactory.getLogger(TimerService.class);
@Override
public void execute(DelegateExecution execution) throws Exception {
LOGGER.info("*** Executing Timer autocomplete ***");
Task task = execution.getEngineservices().getTaskService().createTaskQuery().active().singleResult();
execution.getEngineservices().getTaskService().setvariableLocal(task.getId(),"taskLocalVar","task_local_var_value");
execution.getEngineservices().getTaskService().complete(task.getId());
LOGGER.info("*** Task: {} autocompleted by timer ***",task.getId());
}
}
在完成任务之前请注意这一行
execution.getEngineservices().getTaskService().setvariableLocal(task.getId(),"task_local_var_value");
execution.getEngineservices().getTaskService().complete(task.getId());
这会导致抛出 sql 异常:
[pool-1-thread-2] ERROR org.activiti.engine.impl.interceptor.CommandContext - Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
### The error may involve org.activiti.engine.impl.persistence.entity.ExecutionEntity.deleteExecution-Inline
### The error occurred while setting parameters
### sql: delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ?
### Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultsqlSession.update(DefaultsqlSession.java:172)
at org.apache.ibatis.session.defaults.DefaultsqlSession.delete(DefaultsqlSession.java:185)
at org.activiti.engine.impl.db.DbsqlSession$CheckedDeleteOperation.execute(DbsqlSession.java:293)
at org.activiti.engine.impl.db.DbsqlSession.flushRegularDeletes(DbsqlSession.java:897)
at org.activiti.engine.impl.db.DbsqlSession.flushDeletes(DbsqlSession.java:890)
at org.activiti.engine.impl.db.DbsqlSession.flush(DbsqlSession.java:617)
at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:212)
at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:138)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.handleMultipleJobs(ExecuteJobsRunnable.java:94)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
at org.h2.message.DbException.getJdbcsqlException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.Constraintreferential.checkRow(Constraintreferential.java:426)
at org.h2.constraint.Constraintreferential.checkRowRefTable(Constraintreferential.java:443)
at org.h2.constraint.Constraintreferential.checkRow(Constraintreferential.java:318)
at org.h2.table.Table.fireConstraints(Table.java:967)
at org.h2.table.Table.fireAfterRow(Table.java:985)
at org.h2.command.dml.Delete.update(Delete.java:101)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:201)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:45)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:73)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)
at org.apache.ibatis.session.defaults.DefaultsqlSession.update(DefaultsqlSession.java:170)
... 16 more
[pool-1-thread-2] ERROR org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable - exception during job execution:
### Error updating database. Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
### The error may involve org.activiti.engine.impl.persistence.entity.ExecutionEntity.deleteExecution-Inline
### The error occurred while setting parameters
### sql: delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ?
### Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
### The error may involve org.activiti.engine.impl.persistence.entity.ExecutionEntity.deleteExecution-Inline
### The error occurred while setting parameters
### sql: delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ?
### Cause: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultsqlSession.update(DefaultsqlSession.java:172)
at org.apache.ibatis.session.defaults.DefaultsqlSession.delete(DefaultsqlSession.java:185)
at org.activiti.engine.impl.db.DbsqlSession$CheckedDeleteOperation.execute(DbsqlSession.java:293)
at org.activiti.engine.impl.db.DbsqlSession.flushRegularDeletes(DbsqlSession.java:897)
at org.activiti.engine.impl.db.DbsqlSession.flushDeletes(DbsqlSession.java:890)
at org.activiti.engine.impl.db.DbsqlSession.flush(DbsqlSession.java:617)
at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:212)
at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:138)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.handleMultipleJobs(ExecuteJobsRunnable.java:94)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.h2.jdbc.JdbcsqlException: referential integrity constraint violation: "ACT_FK_VAR_EXE: PUBLIC.ACT_RU_VARIABLE FOREIGN KEY(EXECUTION_ID_) REFERENCES PUBLIC.ACT_RU_EXECUTION(ID_) ('7')"; sql statement:
delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ? [23503-193]
at org.h2.message.DbException.getJdbcsqlException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.Constraintreferential.checkRow(Constraintreferential.java:426)
at org.h2.constraint.Constraintreferential.checkRowRefTable(Constraintreferential.java:443)
at org.h2.constraint.Constraintreferential.checkRow(Constraintreferential.java:318)
at org.h2.table.Table.fireConstraints(Table.java:967)
at org.h2.table.Table.fireAfterRow(Table.java:985)
at org.h2.command.dml.Delete.update(Delete.java:101)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:201)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:45)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:73)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)
at org.apache.ibatis.session.defaults.DefaultsqlSession.update(DefaultsqlSession.java:170)
... 16 more
如果我们将任务变量更改为非本地变量,则会出现类似的异常,例如:
execution.getEngineservices().getTaskService().setvariable(task.getId(),"tasknonlocalVar","task_non_local_var_value");
同样的代码在 Activiti 5.15 版本中成功执行。
可以在以下位置找到示例项目:https://github.com/pleft/DemoActiviti 只需检查 constraint_violation 分支即可。它使用 Activiti 版本 5.22.0
这个异常背后的原因是什么?我们不应该这样设置任务变量(来自计时器执行)吗?从 5.15 到 5.17 发生了什么变化并导致了这种行为?
非常感谢您抽出宝贵时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。