一、起因
    打算使用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. iOS 中 CAShapeLayer 的使用( 等待删除的博文)

    等待删除. 1.CAShapeLayer 简介 1.CAShapeLayer继承至CALayer,可以使用CALayer的所有属性值 2.CAShapeLayer需要与贝塞尔曲线配合使用才有意义 3. ...

  2. java网络---再论URL & URI

    关于URL 和URI的关系,在本系列的第二篇:java网络---基本web概念 中已经简述了. 这里重复一点,就是URI包含URL,或者说URI是父类,URL就是子类的概念. 本篇再来详述这2个概念. ...

  3. Log4net配置文件一般配置

    配置文件一般配置 <?xml version="1.0"?> <configuration> <configSections> <sect ...

  4. Effective Java 65 Don't ignore exceptions

    Principle An empty catch block defeats the purpose of exceptions, which is to force you to handle ex ...

  5. Eclipse 快捷键 篇

    1. Ctrl+Shift+R:打开资源这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xml ...

  6. [转]shell脚本打印日志方法

    该文章转自:http://blog.csdn.net/wylfengyujiancheng/article/details/50019299 ----------------------------- ...

  7. 巧用开发者工具的控制台来调试页面中的js语句

    因为要弄某网页的一个自动登陆工具,所以需要对此网页中的元素利用js进行选取和操作,复杂的js选取如果直接在头脑中想很容易出错,而且一旦出错也不好判断错误原因. 而浏览器带的开发者工具的控制台功能,就给 ...

  8. [转]设定version 更新js缓存

    http://zhenggm.iteye.com/blog/680600 遇到的问题:         在访问量比较大的系统中,我们需要将一些静态的文件在客户端缓存,以减少下载的流量,从而加快客户端访 ...

  9. runv kill 流程分析

    1.runv/kill.go Action: func(context *cli.Context) 该函数做的工作很简单,就是通过grpc客户端,发送一个grpc请求而已,如下: c.Signal(n ...

  10. iOS使用Core Graphics和UIBezierPath绘画

    通过UIView的子类的- (void)drawRect:(CGRect)rect 函数可用对视图进行重新绘画: 要重新绘画可以通过Core Graphics和UIBezierPath来实现. 1.通 ...