Activiti的数据库配置,是每个准备上手这个工作流引擎的开发者绕不开的第一道坎。我见过太多人在跑通第一个Demo之前,就被各种连接报错、表缺失、版本不兼容折磨得怀疑人生。其实这事没那么玄乎,说白了就是告诉Activiti你的数据库在哪儿、怎么连、以及用哪种方言跟它说话。但就是这几句话,说不好,后面全是坑。

先搞清楚Activiti到底要什么样的数据库。它不像某些框架,你说“给我来个内存库”它就能自己变一个出来。Activiti要求你必须有一个真实存在的关系型数据库,MySQL、Oracle、PostgreSQL、H2这些都行。它自己会往库里建一堆表,什么ACTRE、ACTRU、ACTHI、ACTID,光看前缀就知道是干嘛的:RE是流程定义和流程实例的静态资源,RU是运行时的执行实例,HI是历史数据,ID是身份信息。这些表不是让你手动建的,是Activiti启动时自动创建的。但前提是——你得给它正确的数据库连接信息,并且账号得有建表权限。
很多人第一次配置,喜欢直接复制网上的配置片段。我见过一个最典型的错误,用的是MySQL 5.x的驱动,连的却是MySQL 8.x的库,结果启动时报“Public Key Retrieval is not allowed”或者“Unsupported connection charset”。这就是典型的数据库方言和驱动版本不匹配。你用的Activiti版本,它内部封装的MyBatis方言,跟你数据库的版本,还有你JDBC驱动jar包的版本,这三者必须咬合。比如Activiti 5.x时代常用com.mysql.jdbc.Driver,到了Activiti 6.x和7.x,就必须用com.mysql.cj.jdbc.Driver,URL还得加上serverTimezone=UTC这种参数,否则时区问题能让你查出来的时间全差8小时。
再说连接池。Activiti默认用的是自带的数据源,但你最好别这么干。生产环境里,你得把它交给Spring或者Spring Boot来管理,用HikariCP或者Druid。为什么?因为Activiti自带的连接池太“天真”了,在高并发下连接不够用,或者长时间空闲被数据库踢掉,它不会自动重连,直接抛异常。你想象一下,一个审批流程跑到一半,突然数据库连接断了,整个流程实例卡在那里,所有待办任务全部瘫痪。这可不是危言耸听,我亲眼见过一个客户的生产环境,就是没配连接池的保活机制,每周五下午必崩一次,后来发现是数据库的waittimeout默认8小时,连接池里的连接超过8小时没活动,被MySQL杀了,Activiti还傻傻地拿着死连接去查询。
配置里还有个容易忽略但致命的点——表前缀。Activiti默认的表前缀是空字符串,就是直接用ACTRE这样。但如果你一个数据库里同时跑多个Activiti应用,或者跟别的业务表混在一起,名字冲突是迟早的事。这时候你就得设置databaseTablePrefix。比如你给每个应用分配一个前缀,像“wfACTRE”。但注意,这个前缀不是随便加的,它会影响Activiti内部的SQL语句拼接,如果你改了前缀,但没同步改Activiti的quartz表配置,或者没在流程引擎配置里指定,那启动时就会报“Table 'xxxACTGEPROPERTY' doesn't exist”。我建议,除非你有极强的理由,否则别动表前缀这个参数,保持默认最省心。
再说一个进阶但很实用的配置:databaseSchemaUpdate。这个参数有几个取值:false、true、create-drop。默认是false,意思是Activiti启动时不会检查表结构,如果你表没建,它就直接报错。true是启动时检查,发现缺表就自动建,有旧表就自动更新结构。create-drop是启动时建表,关闭时删表,这种只适合纯测试用。我见过有人图省事,生产环境直接配true,结果某次升级Activiti版本,它自动往表里加了个新字段,但没加索引,结果查询性能直线下降。所以生产环境,一定用false,然后手动执行官方提供的建表SQL脚本,把表结构牢牢控制在自己手里。升级版本时,先对比官方SQL脚本的差异,手动执行ALTER TABLE,别让Activiti自己去改。
数据库隔离级别也得提一嘴。Activiti的流程实例、任务、执行实例这些表,在并发审批时,如果隔离级别设成READUNCOMMITTED,那可能读到脏数据,导致流程状态错乱。我推荐用MySQL默认的REPEATABLEREAD,或者干脆用READCOMMITTED,但别为了性能去调低隔离级别。另外,锁机制也很关键。Activiti在更新流程实例状态时,会使用悲观锁,也就是SELECT ... FOR UPDATE。如果你的事务隔离级别太低,或者表引擎不支持行锁(比如MyISAM),那并发控制就形同虚设。所以,用MySQL的话,表引擎一定要用InnoDB,别用MyISAM,否则并发一上来,轻则死锁,重则数据损坏。
说说配置文件的组织方式。现在主流是Spring Boot,那就直接在application.yml或application.properties里写。核心配置就这几行:spring.datasource.url、spring.datasource.username、spring.datasource.password、spring.datasource.driver-class-name。然后Activiti自己的配置,比如activiti.database-schema-update、activiti.db-history-used、activiti.history-level。其中history-level很关键,它决定你历史数据保留的粒度:none只保存流程实例,activity保存活动实例,audit保存所有流程变量和表单数据,full则连变量更新前后的值都记录。配置越大,存储和查询压力越大,但排查问题越方便。我一般建议生产环境用audit,别用full,除非你有审计合规要求。
Activiti数据库配置,看起来就是个连接串加上几个布尔值,但真正玩透了,你会发现它其实是整个工作流引擎稳定性的地基。连接池、事务隔离、表结构管理、历史数据策略,每一个小参数背后都对应着一种运行时的行为模式。我见过太多项目,流程图画得漂亮,审批逻辑设计得精巧,结果因为数据库配置不当,上线第一天就被锁表搞趴下。所以,别嫌配置繁琐,花点时间把每个参数的含义和影响琢磨清楚,比多写几个流程节点有价值得多。你把它配好了,Activiti就是你手里的瑞士军刀;配不好,它就是一把随时会走火的枪。


