标签:jbpm
随着系统的运行我的工作我起草查询出现了这样一个bug:工作列表中的当前步骤与历史中的当前环节并不符合。如下
找到我起草这一块的sql,如下:
LEFT JOIN T_BPM_PROCESS_TASK task ON task.processExecutionId = Execution.id AND task.taskId= ( select max(taskId) from T_BPM_PROCESS_TASK task2 where task2.processExecutionId = Execution.id)
左连接task的activityName即为当前步骤。以上逻辑是基于taskId是按照某种规则向上增长的,先处理的环节的taskId肯定比后处理的taskId小,但通过这个例子,也已经发现taskId并不严格按照向上增长的规律变化。
找到创建新任务的入口(TaskServiceImpl)
commandService.execute(new NewTaskCmd(parentTaskId))
这是一个命令模式,进入NewTaskCmd,进入execute()方法,再进入DBSessionImpl的createNewTask()方法,然后是createTask(),在这个方法里有的生成方法
long dbid = EnvironmentImpl.getFromCurrent(DbidGenerator.class).getNextId();
上面是反射的应用,进到DbidGenerator的方法getNextId(),这是一个被同步的方法,每次只能有一个调用进入。我们再依次进入核心的方法acquireDbidBlock(),然后又是一个命令模式,AcquireDbidBlockCmd的execute,下面我们可以看到
PropertyImpl property = (PropertyImpl) session.createCriteria(PropertyImpl.class) .add(Restrictions.eq("key", PropertyImpl.NEXT_DBID_KEY)) .uniqueResult();
我们打开jbpm_property,里面有一条数据,指定的是id的生成方法以及步长。
打开jbpm.task.hbm.xml可以看到
<id name="dbid" column="DBID_"> <generator class="assigned" /> </id>
通过ibernate的generator属性的意义这篇文章,我们可以知道assigned的用法,即
assigned(程序设置)
让应用程序在save()之前为对象分配一个标示符,在save前通过自定义的id生成器生成了id。
Activiti5出自Tom之手,在DBID生成器的实现这块是一样的,下面是一篇对activiti5的ID自定义生成器的解释:
2、activiti5的默认主键策略分析:
(1)每次需要主键的时候从act_ge_property表中的next.dbid中获取下一个主键值,但是主键增长步长是100,也就是说每次从这里获取下一个值的时候,上次是100,下次的值是200.
(2)他们所有需要主键的表都从这个表中获取下一个值
(3)但是他们针对性能做了一个取巧处理,就是每次步长100,将这个步长cache在本地用sychronize方法调用,也就是说一段时间内只需要在本地获取主键即可,不需要访问数据实时更新,一定程度的缓解了数据库调用压力
(4)但是对于高并发来说,这个只能局部缓解,并发写入压力,还是有造成主键重复的概率
通过以上的解释,不难发现为什么jbpm4的DBID会出现小的情况,这与主键重复的原理是相似的。
通过以上分析,我们将我起草的查询逻辑改为:
AND task.createTime = ( select max(createTime) from T_BPM_PROCESS_TASK task2 where task2.processExecutionId = Execution.id limit 1)
本文出自 “南湖矿工技术空间” 博客,请务必保留此出处http://jncumter.blog.51cto.com/812546/1651047
标签:jbpm
原文地址:http://jncumter.blog.51cto.com/812546/1651047