一、起因
    打算使用activiti的定时启动事件来定时启动流程,然后再在该流程中针对每个用户启动另外一个流程实例来计算每个用户的实时账单,系统的用户数一般是1000~2000(此处假设是2000),实时账单一般每小时计算一次,那么一天的数据量就是 2000x24=48000,一个月就是150w,一年就是1800w,这样的记录数对于activiti的历史表来说就有点多了,很怀疑他在这样的数据量下是否还可以跑得比较顺畅。我想activiti设计的初衷不是用来做这种大规模的自动触发的、没有人工参与的流程的。
    所以就考虑是不是通过某些设置,可以让这种自动执行的流程不用写历史表,但是其他的需要人工参与的流程还是要能够正常记录历史记录。
    

二、源码阅读    
    然后就阅读了activiti 5.18的源码,分析如下:
    写历史表示在DefaultHistoryManager,中实现的,通过HistoryLevel来控制,相关的代码如下:
  1. public void recordProcessInstanceStart(ExecutionEntity processInstance) {
  2. if(isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
  3. HistoricProcessInstanceEntity historicProcessInstance = new HistoricProcessInstanceEntity(processInstance);
  4. // Insert historic process-instance
  5. getDbSqlSession().insert(historicProcessInstance);
  6. ....
  7. }

而isHistoryLevelAtLeast的实现如下:
  1. public boolean isHistoryLevelAtLeast(HistoryLevel level) {
  2. if(log.isDebugEnabled()) {
  3. log.debug("Current history level: {}, level required: {}", historyLevel, level);
  4. }
  5. // Comparing enums actually compares the location of values declared in the enum
  6. return historyLevel.isAtLeast(level);
  7. }


HistoryLevel枚举类型的是实现如下
  1. /**
  2. * Enum that contains all possible history-levels.
  3. *
  4. * @author Frederik Heremans
  5. */
  6. public enum HistoryLevel {
  7. NONE("none"),
  8. ACTIVITY("activity"),
  9. AUDIT("audit"),
  10. FULL("full");
  11. private String key;
  12. private HistoryLevel(String key) {
  13. this.key = key;
  14. }
  15. /**
  16. * @param key string representation of level
  17. * @return {@link HistoryLevel} for the given key
  18. * @throws ActivitiException when passed in key doesn't correspond to existing level
  19. */
  20. public static HistoryLevel getHistoryLevelForKey(String key) {
  21. for(HistoryLevel level : values()) {
  22. if(level.key.equals(key)) {
  23. return level;
  24. }
  25. }
  26. throw new ActivitiIllegalArgumentException("Illegal value for history-level: " + key);
  27. }
  28. /**
  29. * String representation of this history-level.
  30. */
  31. public String getKey() {
  32. return key;
  33. }
  34. /**
  35. * Checks if the given level is the same as, or higher in order than the
  36. * level this method is executed on.
  37. */
  38. public boolean isAtLeast(HistoryLevel level) {
  39. // Comparing enums actually compares the location of values declared in the enum
  40. return this.compareTo(level) >= 0;
  41. }
  42. }

可以看出,是否要在历史记录表中记录流程执行信息,是由 DefaultHistoryManager的level成员来决定的,只有在ACTIVITY及其以上级别才会记录。
DefaultHistoryManager是全局的,和某个具体的流程或者流程实例是没有关系的,所以在默认实现中,activiti不支持设置单个流程或者流程实例是否写历史记录表。
 
三、解决方案
如果我们真的想要实现针对每个流程或者流程实例都可以控制他是否写日志,要有两点修改:
1.要给ExecutionEntity添加一个HistoryLevel属性,或者流程变量,可能用流程变量更方便一些,就不需要对原有的类做改动了;
2.要实现一个自定义的HistoryManager,然后注入到CommandContext中。在这个自定义的HistoryManager中需要能够判断ExecutionEntity的HistoryLevel的等级,以决定是否需要记录他的历史信息;

Activiti系列:是否可以让某些流程的信息写到历史表,而另外一些不写?的更多相关文章

  1. 玩转Windows服务系列——服务运行、停止流程浅析

    通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大家可要睁大眼睛看清楚了. 接下来研究一下Windows服务的 ...

  2. Activiti工作流学习(二)流程实例、执行对象、任务

    一.前言 前面说明了基本的流程部署.定义,启动流程实例等基本操作,下面我们继续来学习流程实例.执行对象.任务. 二.流程实例.执行对象说明 整个Activiti的生命周期经过了如下的几个步骤: 1.流 ...

  3. activiti系列导读

    此用于管理activiti系列标签文章,activiti的分析是建立在目前最新的版本5.21之上. 官方指导手册链接:http://www.activiti.org/userguide/index.h ...

  4. 玩转Windows服务系列——服务运行、停止流程浅析

    原文:玩转Windows服务系列——服务运行.停止流程浅析 通过研究Windows服务注册卸载的原理,感觉它并没有什么特别复杂的东西,Windows服务正在一步步退去它那神秘的面纱,至于是不是美女,大 ...

  5. Activiti进阶(二)——部署流程资源的三种方式

    转自:http://blog.csdn.net/zjx86320/article/details/50234707 流程资源可以是各种类型的文件,在启动流程或流程实例运行过程中会被读取.下面介绍常用的 ...

  6. 【Activiti学习之七】BPMN子流程、顺序流、流程关口

    环境 JDK 1.8 MySQL 5.6 Tomcat 7 Eclipse-Luna activiti 6.0 一.子流程 1.嵌入子流程2.调用子流程3.事件子流程4.事务子流程 二.顺序流1.条件 ...

  7. Spring框架系列(5) - 深入浅出SpringMVC请求流程和案例

    前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC:Spring MVC是Spri ...

  8. Activiti工作流框架学习(一)——环境的搭建和数据表的了解

    一.什么是工作流 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现 ...

  9. JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)

    前言:上篇 JS组件系列——表格组件神器:bootstrap table 简单介绍了下Bootstrap Table的基础用法,没想到讨论还挺热烈的.有园友在评论中提到了父子表的用法,今天就结合Boo ...

随机推荐

  1. 小波说雨燕 第三季 构建 swift UI 之 UI组件集-视图集(四)Alert View视图 学习笔记

    当我们的应用电量不足的时候,就需要警告提示,那么我们可以用Alert View视图 实现:    

  2. 【SVN】Unable to connect to a repository at URL 'svn://localhost/Test'

    早上配置SVN,但是这次不是那么顺利... 环境: Windows 7 SVN服务器端:CollabNetSubversion-server-1.8.13-1 SVN客户端:TortoiseSVN_V ...

  3. 关于zend_parse_parameters函数

    PHP_FUNCTION(set_time_limit) { long new_timeout; char *new_timeout_str; int new_timeout_strlen; if ( ...

  4. Bootstrap(转)

    Bootstrap 随着互联网的不断成熟以及我们越来越多的用各种移动端的设备访问互联网,Web设计师和Web开发者的工作也变得越来越复杂. 十年前,一切都还简单得多.那个时候,大部分用户都是坐在桌子前 ...

  5. Mongo 的相关增删改查

    1,Mongod 下载安装,请看https://www.mongodb.com/download-center 2,插入语句: MongoDB后台管理 Shell 如果你需要进入MongoDB后台管理 ...

  6. linux命令详解之挂载光驱的方法

    linux的硬件设备在/dev目录下,光驱也是其中./dev/cdrom表示光驱,挂载光驱的方法如下(以root身份): 代码如下: mkdir /mnt/cdrommount  -t auto  - ...

  7. linux多线程同步pthread_cond_XXX条件变量的理解

    在linux多线程编程中,线程的执行顺序是不可预知的,但是有时候由于某些需求,需要多个线程在启动时按照一定的顺序执行,虽然可以使用一些比较简陋的做法,例如:如果有3个线程 ABC,要求执行顺序是A-- ...

  8. 【开学季】自学嵌入式开发|四核开发板|4412开发板|ARM+Android+linux技术

    淘宝店铺:迅为开发板http://arm-board.taobao.com 网站:http://www.topeetboard.com QQ咨询:2551456065 电话咨询:010-5895758 ...

  9. 调用手机话费充值API的SDK编写思路

    思路 通过将SDK方法中返回的数据划分为正常返回数据以及错误返回的数据两部分,让调用者更简单的对接口调用错误进行处理. 将SDK调用第三方服务接口的流程划分为: 数据准备,http请求,结果处理三部分 ...

  10. 关于volatile和synchronized

    这个可能是最好的对比volatile和synchronized作用的文章了.volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符.所以我们使用这两种关键字来指定三种简单的 ...