news 2026/9/16 0:35:00

Flowable多数据源整合PostgreSQL指定Schema实战与避坑总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flowable多数据源整合PostgreSQL指定Schema实战与避坑总结

前阵子帮一个老项目接 Flowable,需求听起来很简单:业务表继续留在主库里,流程引擎那几十张 ACT_ 开头的表放到独立数据源,并且 PostgreSQL 环境下还得落到指定 schema 里。结果从配置到跑通整整折腾了两个下午,期间踩过的坑包括但不限于:引擎把表建到了 public schema、多数据源事务互相串、以及被一个看起来像 Flowable 报错、实际是 API 校验的 invalid schema 错误误导了半天。这篇就把这段实战经验完整复盘一遍,从多数据源装配、指定 Schema 的原理,到常见的翻车现场和排查思路,一次性讲透,适合正在做 Flowable 集成、或者准备把工作流引擎从业务库中隔离出来的同学参考。

1. 场景设定与整体设计思路

1.1 为什么业务库和数据源必须分离

Flowable 作为 Java 生态里最主流的 BPMN 工作流引擎之一,开箱即用确实方便,但它默认行为很“霸道”:一旦你把flowable-spring-boot-starter-process引入工程,它就会自动寻找容器里的主数据源,把 ACT_GE_、ACT_RU_、ACT_HI_、ACT_ID_ 这几大类几十张表全部建进去。

如果你在项目初期就把流程表和业务表混在同一个库,前期开发没感觉,到了后面会非常难受:

  • 备份恢复很被动。业务数据天天在变,流程历史数据也在暴涨,混在一起备份,要么备份文件巨大,要么想单独恢复某张业务表时被 ACT_HI_ACTINST 这种大表拖累。
  • 权限粒度没法控制。DBA 希望应用账号只能读写业务表,流程引擎的账号单独管理,混库以后很难实现。
  • 迁移和发布有风险。业务库做结构变更、分库分表的时候,引擎表会跟着受影响,一旦误操作,整个流程引擎直接瘫掉。
  • 性能互相干扰。流程引擎大量写入 ACT_HI_ 历史表,业务报表查询也在跑,同一个数据库实例和连接池里互相争抢资源。

所以把 Flowable 独立出来,不只是“多配一个数据源”这么简单,本质上是把工作流引擎当成一个独立的基础设施来对待,和业务系统之间只通过 API 交互,底层数据完全隔离。

1.2 三种多数据源方案怎么选

我整理了一下,常见的方案其实有三种,各有适用场景:

方案隔离程度配置复杂度适用场景
独立数据库实例最高,物理隔离高,需单独维护实例大型系统、强隔离要求、跨团队运维
同实例独立库/独立 Schema中高,逻辑隔离中,配置相对简单大多数中大型单体/微服务项目
同库表前缀隔离低,仅表名区分小项目、快速原型、实在没有数据库权限

方案三用的是spring.flowable.table-prefix这个配置,让引擎表带上前缀,比如FLW_ACT_GE_PROPERTY。它虽然省事,但业务库里的表还是混在一起,前面说的备份、权限、性能问题一个都没解决。

方案一物理隔离最干净,但一般公司没那么多数据库实例资源。折中下来,绝大多数项目最合理的方案就是方案二:同一个 MySQL 实例里建一个独立 database,或者同一个 PostgreSQL 实例里建一个独立 schema,然后给 Flowable 单独配一个数据源账号。这也正是我这次实战采用的方案。

1.3 指定 Schema 到底在解决什么问题

很多人第一次看到databaseSchema这个配置会懵,其实“Schema”这个概念在不同的数据库里含义不太一样:

  • MySQL:Schema 基本等同于 Database。你执行CREATE DATABASE flowable_db,等于创建了一个 schema,表名完整写法就是flowable_db.act_ge_property
  • PostgreSQL:Schema 是数据库内部的一层命名空间,一个数据库可以有好几个 schema,默认情况下表会建到public这个 schema 里,完整写法是flowable.act_ge_property
  • Oracle:一个用户对应一个 Schema,权限天然隔离,这个其实是 Oracle 的设计好处。
  • SQL Server:Schema 是数据库内的命名空间,默认dbo

Flowable 里的databaseSchema配置,就是告诉引擎“你建表和读写表的时候,给我的表名加上哪个前缀”。比如设置成flowable,生成的 SQL 就会变成select * from flowable.act_ru_execution。对于 MySQL,由于 schema 就是数据库名,直接在 JDBC URL 里带上库名就行,databaseSchema填不填影响不大;但对于 PostgreSQL,如果不指定当前 schema 或者不设置databaseSchema,引擎就会老老实实找默认的public,然后你会在public里看到一堆 ACT_ 表,这就是很多人踩的第一个坑。

2. 前置准备与关键配置项

2.1 版本搭配参考

Flowable 的版本和 Spring Boot 的版本强相关,配错版本很容易出现莫名其妙的兼容性问题。我这次用的是 Spring Boot 2.7 搭配 Flowable 6.7.2,这是目前比较稳的组合:

Spring Boot 版本Flowable 版本JDK说明
2.7.x6.7.2 或 6.8.x8/11/17经典组合,资料最多,最稳妥
2.7.x6.6.08/11老项目常见,升级需注意
3.x7.0.0+17新版引擎,包结构和配置有调整
3.2.x+7.1.0+17/21新特性多,但踩坑资料相对少

有个点必须注意:Flowable 6 和 7 的某些 API 有变化,而且数据库表结构也不同。如果你从 5.x 直接升 6.x,不能指望database-schema-update: true帮你自动完成,版本跨度太大时就得跑官方迁移脚本。所以生产环境里,Flowable 引擎 JAR 版本和数据表里ACT_GE_PROPERTY记录的 schema.version 要保持一致,这个后面避坑章节会展开讲。

2.2 数据库实例与账号权限准备

我这次是 PostgreSQL 环境,需要单独建一个 schema 和一个专用账号:

-- 进入 flowable_db 数据库后执行 CREATE SCHEMA IF NOT EXISTS flowable AUTHORIZATION flow_user; -- 创建专用账号,只管理 flowable 相关对象 CREATE USER flow_user WITH PASSWORD 'flow_pass'; GRANT USAGE, CREATE ON SCHEMA flowable TO flow_user; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA flowable TO flow_user; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA flowable TO flow_user; ALTER DEFAULT PRIVILEGES IN SCHEMA flowable GRANT ALL ON TABLES TO flow_user; ALTER DEFAULT PRIVILEGES IN SCHEMA flowable GRANT ALL ON SEQUENCES TO flow_user;

如果是 MySQL,就简单一些:

CREATE DATABASE flowable_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'flow_user'@'%' IDENTIFIED BY 'flow_pass'; GRANT ALL PRIVILEGES ON flowable_db.* TO 'flow_user'@'%'; FLUSH PRIVILEGES;

权限这里有个容易忽略的地方:如果你设置了database-schema-update: true,引擎启动时会自己去建表、加索引,那么数据库账号必须拥有 DDL 权限(CREATE、ALTER、INDEX)。如果公司安全规范不允许应用账号有 DDL 权限,那就得先手动执行 Flowable 提供的建表脚本,然后把database-schema-update设为false,只保留 DML 权限。

2.3 Flowable 核心配置项逐个说清

配置 Flowable 时主要围绕这几个参数,弄明白参数背后的逻辑,比死记配置语句有用得多:

配置项可选值作用
spring.flowable.database-schema-updatetrue/false/create-drop是否自动建表/升级表结构
spring.flowable.database-schema字符串指定引擎表所在 Schema,PG 下尤其关键
spring.flowable.table-prefix字符串表名前缀,比如FLW_,用于同库隔离方案
spring.flowable.history-levelnone/activity/audit/full历史数据记录粒度,直接影响 ACT_HI_ 表数据量
spring.flowable.async-executor-activatetrue/false是否启动异步执行器处理定时任务、异步消息

关于database-schema-update,网上很多人直接写true图省事,我建议生产环境谨慎。true的意思是“没有表就建,字段缺了就补”,听起来很智能,但引擎升级时它不会帮你做破坏性变更,遇到大版本切换该报错还是报错。而且一旦给了 DDL 权限,万一代码里有人手滑把databaseSchemaUpdate改掉,生产库结构会被自动改动,风险很大。我的习惯是:开发环境开true,测试和生产环境用官方 SQL 脚本手动建表,然后设false

3. 从零到一:多数据源与指定 Schema 的完整落地

3.1 用 ConfigurationProperties 装配两个 DataSource

先看最终的application.yml,多数据源的思路是给业务库和 Flowable 库各自定义一组spring.datasource.*配置,用自定义前缀区分:

spring: datasource: business: driver-class-name: org.postgresql.Driver jdbc-url: jdbc:postgresql://192.168.1.10:5432/business_db?currentSchema=business&stringtype=unspecified username: bus_app password: bus_pass hikari: pool-name: BusinessPool maximum-pool-size: 20 minimum-idle: 5 flowable: driver-class-name: org.postgresql.Driver jdbc-url: jdbc:postgresql://192.168.1.10:5432/business_db?currentSchema=flowable&stringtype=unspecified username: flow_user password: flow_pass hikari: pool-name: FlowablePool maximum-pool-size: 10 minimum-idle: 2 flowable: database-schema-update: true database-schema: flowable history-level: audit async-executor-activate: true

这里有一个很有迷惑性的细节:业务库和 Flowable 库可以不在同一个数据库实例上,我这个例子里 Flowable 的 URL 特意写的是business_db?currentSchema=flowable,意思是“同一个 PostgreSQL 实例、同一个数据库内,使用 flowable 这个 schema”。如果你更希望物理分开,那 Flowable 的jdbc-url就指向另一个数据库实例,原理完全一样。

注意 PG 连接串里的currentSchema=flowable,这个参数非常关键。PostgreSQL JDBC 驱动通过它来设置连接默认搜索路径,连接建立之后,不带 schema 前缀的表名就会先去flowable这个 schema 里找。配合stringtype=unspecified,可以避免某些情况下字符串类型被错误推断的问题,算是 PG 连接 Flowable 的老经验了。

然后定义数据源 Bean,两个数据源必须区分清楚谁是主:

import com.zaxxer.hikari.HikariDataSource; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class MultiDataSourceConfig { @Bean @Primary @ConfigurationProperties(prefix = "spring.datasource.business") public DataSource businessDataSource() { return DataSourceBuilder.create() .type(HikariDataSource.class) .build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.flowable") public DataSource flowableDataSource() { return DataSourceBuilder.create() .type(HikariDataSource.class) .build(); } }

关键在于@Primary注解必须放在业务数据源上。Spring Boot 里的自动配置、MyBatis、JPA 这些组件,默认情况下拿到的是唯一的或带@Primary的数据源。我们希望业务框架仍然使用业务库,所以主数据源必须是业务库,Flowable 这个特殊数据源则由后面专门的配置类去引用。

有个小提示:使用DataSourceBuilder时配置项要写jdbc-url而不是url,因为 HikariCP 内部的真实属性名是jdbcUrl,Spring Boot 的宽松绑定会把jdbc-url映射过去。如果写成url,启动时大概率会报“DataSource 属性绑定失败”。

3.2 通过 ProcessEngineConfigurationConfigurer 接管引擎数据源与事务

有了两个数据源 Bean 之后,重点来了:怎么让 Flowable 引擎不要用主数据源,而是用flowableDataSource

网上很多教程会让你排除FlowableAutoConfiguration,然后手动创建ProcessEngine、各个 Service Bean,这个方案能行但代码量很大,而且容易漏。其实官方早就提供了更优雅的口子:ProcessEngineConfigurationConfigurer

这个接口的作用是在引擎配置对象构建完成、但 ProcessEngine 还没创建之前,给你一个修改配置的机会。我们可以在这个回调里把数据源和事务管理器换成 Flowable 专用的:

import org.flowable.spring.ProcessEngineConfigurationConfigurer; import org.flowable.spring.SpringProcessEngineConfiguration; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @Configuration public class FlowableEngineConfig { @Bean public ProcessEngineConfigurationConfigurer flowableEngineConfigurer( @Qualifier("flowableDataSource") DataSource flowableDataSource, @Qualifier("flowableTxManager") PlatformTransactionManager flowableTxManager) { return new ProcessEngineConfigurationConfigurer() { @Override public void configure(SpringProcessEngineConfiguration config) { config.setDataSource(flowableDataSource); config.setTransactionManager(flowableTxManager); config.setDatabaseSchema("flowable"); config.setDatabaseSchemaUpdate("true"); config.setHistoryLevel(HistoryLevel.AUDIT); config.setAsyncExecutorActivate(true); } }; } }

setDataSource不用多解释,关键是setTransactionManager。Flowable 与 Spring 整合后,Service 层操作的事务边界是由PlatformTransactionManager控制的,如果你不指定,引擎会去 Spring 容器里找,但此时容器里有业务库和 Flowable 库两个事务管理器,很容易选错。所以必须在配置里明确告诉引擎:你的事务管理器是绑定 Flowable 数据源的那个。

setDatabaseSchema("flowable")的作用是和currentSchema=flowable双保险。引擎建表和读写 SQL 时,会尝试给表名加上 schema 前缀。对于 PostgreSQL 来说,如果没有这个配置,即使 JDBC URL 里带了currentSchema,某些版本的 Flowable 在 DDL 阶段仍可能把表建到public,这个后面避坑章节再展开。

3.3 指定 Schema 的几种实操姿势与底层原理

关于“指定 Schema”,我实际用下来有三种姿势,分别适用不同场景:

姿势一:JDBC URL 参数指定(推荐)。

PostgreSQL 用currentSchema,这个参数由驱动层设置连接默认搜索路径;MySQL 则直接把库名写在 URL 里。这种方式在连接层面就锁定了 schema 范围,最可靠。比如jdbc:postgresql://host:5432/business_db?currentSchema=flowable,连接建立后,未加前缀的ACT_RU_EXECUTION会优先在flowableschema 里解析。

姿势二:Flowable 配置属性指定。

spring.flowable.database-schema=flowable或者代码里config.setDatabaseSchema("flowable")。这个属性会被引擎用来在 DML/DDL 语句中拼接 schema 前缀,例如生成的 SQL 会变成insert into flowable.act_ru_execution(...)。注意 MySQL 下如果填了 schema 名,务必和 URL 里的库名保持一致,否则可能出现flowable_db.act_ge_property这种双重前缀的 SQL。

姿势三:SQL 里显式 set search_path。

这个往往被忽略,但在排查问题时很好用。数据库侧执行:

ALTER ROLE flow_user IN DATABASE business_db SET search_path TO flowable, public;

这属于数据库层面的默认设置,相当于给这个角色在连接时自动执行SET search_path。如果应用配置没法轻易改,用这个方式也能解决 PG 下 schema 匹配问题。

三种姿势的背后原理是同一个:Flowable 在生成 SQL 时,表名最终要能在数据库里唯一解析。要么驱动层帮你想好默认 schema,要么引擎层主动拼前缀,两者至少有一个生效,否则必然落到public

3.4 事务边界要分清:业务管理器与流程管理器的分工

多数据源的难点不只是数据源本身,事务管理器是另一个很容易炸的地方。我们最终在容器里要有两个PlatformTransactionManager

@Bean @Primary public PlatformTransactionManager businessTxManager( @Qualifier("businessDataSource") DataSource businessDataSource) { return new DataSourceTransactionManager(businessDataSource); } @Bean public PlatformTransactionManager flowableTxManager( @Qualifier("flowableDataSource") DataSource flowableDataSource) { return new DataSourceTransactionManager(flowableDataSource); }

业务代码里凡是用@Transactional的地方,默认会走businessTxManager,因为它有@Primary。而引擎内部的 Service 调用走的是flowableTxManager,因为我们在ProcessEngineConfigurationConfigurer里显式指定了。

实际开发中容易犯的错误是:在一个业务事务里同时操作业务表和 Flowable 服务,比如:

@Transactional public void createOrderAndStartProcess() { orderMapper.insert(order); runtimeService.startProcessInstanceByKey("orderProcess"); }

这段代码乍一看没问题,但它隐含了一个大坑:业务事务和流程引擎事务是两个独立事务,orderMapper.insert提交失败时,流程实例可能已经启动了,反之亦然。多数据源本身不具备分布式事务能力,不要把跨库操作硬塞进一个@Transactional里。真需要原子性,要么引入 Atomikos 这类 XA 事务方案,要么用本地消息表加补偿任务,从架构层面规避。

4. 实战避坑:最常见的五个翻车现场

4.1 建表失败:先分清“数据库 Schema”还是“API Schema”

搜索 Flowable schema 相关报错时,你可能会搜到形如:api error: 400 invalid schema for function 'artifact': "^(?!.*$)[^\p{cc}\p{cf}\p{zl}\p{zp}\"\./[\]]{1,200}$" is not a "regex"这样的错误。我一开始也以为是 Flowable 的表结构校验报错,后来仔细一看完全不是一回事。

这种报错的典型特征很明显:带api error400function,并跟着一串正则表达式。它通常来自 API 网关或者 AI 代理工具,是“函数参数校验 schema”(一般是指 JSON Schema)定义不合法,和数据库 schema 没有半毛钱关系。Flowable 里的 schema 永远是指数据库里的命名空间,报错形式一般是 SQLState、JDBC 异常,或者org.flowable.common.engine.api.FlowableException开头的引擎异常。

所以排查第一步,先看错误类型。数据库 schema 跑偏的报错,核心信息里会有表名和 schema 名,比如:

ERROR: schema "flowable" does not exist

或者:

Unknown database 'flowable_db'

这类才是 Flowable 数据源配置的问题。看到一个 400 加一堆正则的报错,先去检查你的 HTTP 接口定义和工具参数格式,不要在 Flowable 配置里浪费时间。

4.2 表建到了默认库/默认 Schema

这是多数据源配置里出现频率最高的问题,表现是:业务系统正常启动,ACT_ 表也建出来了,但出现在public(PG)或者业务库(MySQL)里,而不是预期的 schema。

常见原因有三个:

原因一:JDBC URL 没带 schema 参数。PostgreSQL 下如果 URL 没写currentSchema,配置里又没设置databaseSchema,引擎会用数据库默认的public。解决方式就是前面说的,URL 加currentSchema,配置里再补setDatabaseSchema

原因二:@Primary放错了位置。如果flowableDataSource不小心被加了@Primary,其他框架会优先用它,业务 SQL 全部跑到了流程库;更隐蔽的是,某些自动配置判断主数据源时也会取到 Flowable 数据源,导致引擎加载的构造配置混乱。

原因三:多个ProcessEngineConfigurationConfigurer互相覆盖。如果项目里之前有人写过一个 configurer 把dataSource设成了主数据源,而你又新增了一个 configurer 设置流程数据源,Bean 的执行顺序不确定,后执行的那个会覆盖前一个。这种问题特别隐蔽,建议先全局搜一下有没有其他ProcessEngineConfigurationConfigurer实现。

排查时用一条 SQL 就能确认表到底建到了哪:

-- MySQL SELECT table_schema, table_name FROM information_schema.tables WHERE table_name LIKE 'ACT\_%'; -- PostgreSQL SELECT table_schema, table_name FROM information_schema.tables WHERE table_name LIKE 'ACT\_%';

如果结果里 schema 不是预期值,先把两处配置(URL + databaseSchema)都改对,再删掉建错的表重新启动。

4.3 schema.version 不匹配

另一个高频报错是启动时抛类似这样的异常:

org.flowable.common.engine.api.FlowableException: Could not find a valid Flowable database version

或者:

Flowable database schema version mismatch

这个错误的根源是ACT_GE_PROPERTY表里记录了schema.version,引擎启动时会拿这个值和当前 JAR 包里的版本做比对。常见场景是:老项目升级 Flowable JAR 版本,但数据库表没有跟着升级;或者 pom 里同时引入了多个 Flowable 模块,版本号不一致。

处理方式很直接:

  • 先检查 pom 里所有org.flowable相关依赖版本是否一致,统一用<flowable.version>属性管理。
  • 小版本升级(比如 6.7.1 到 6.7.2),设database-schema-update: true让它自动升级。
  • 跨大版本(6.x 到 7.x),不要指望自动升级,先用官方升级脚本,或者对比ACT_GE_PROPERTY中的 schema.version 与目标版本,按官方文档执行迁移。

这里还要提醒一句:别为了绕过版本检查把ACT_GE_PROPERTY里的版本号手工改掉,数据库结构和引擎代码不匹配,后面会冒出一堆字段不存在、存储过程调用失败的问题,远比版本检查报错难查。

4.4 多数据源事务串了导致写错库

这类问题表现特别诡异:业务代码里用@Transactional调用流程引擎服务,结果流程数据写到了业务库;或者反过来,流程执行过程中把业务表数据搞进去了。

从原理上讲,这通常是事务管理器选错了。DataSourceTransactionManager绑定的是具体哪个DataSource,它负责的 Connection 就是从那个数据源拿的。如果引擎的 transactionManager 没显式设置,Flowable 的 Spring 整合代码会尝试从容器中找一个事务管理器,而容器里有多个时,很可能拿到带@Primary的业务事务管理器。引擎拿着业务事务管理器,事务同步时绑定的资源是业务数据源的,但引擎 Service 内部拿连接时又去 flowableDataSource 获取,两边对不上,写库就乱了。

解决办法就是 3.2 节的做法:在ProcessEngineConfigurationConfigurer里显式setTransactionManager(flowableTxManager)。配置完之后,可以通过一个简单的自检接口确认:

@Autowired @Qualifier("flowableTxManager") private PlatformTransactionManager flowableTxManager; @Autowired private ProcessEngine processEngine; public void check() { SpringProcessEngineConfiguration config = (SpringProcessEngineConfiguration) processEngine.getProcessEngineConfiguration(); System.out.println("Engine DataSource = " + config.getDataSource()); System.out.println("Engine TxManager = " + config.getTransactionManager()); System.out.println("Engine schema = " + config.getDatabaseSchema()); }

把这三样打出来,数据源和事务管理器是不是 Flowable 专用的,一眼就能看出来。

4.5 连接池配置不当导致引擎启动假死

最后一个坑比较隐蔽,表现是应用启动日志停在“Initializing process engine...”很久,然后超时失败,或者偶尔启动成功但异步任务一多就大量报错。

常见原因是 Flowable 数据源的连接池maximum-pool-size设置得太小。Flowable 的异步执行器会在线程池里跑定时任务、消息任务,一个事务就要占用一个连接。如果连接池上限是 1,引擎初始化时建表事务和异步任务初始化并发抢连接,就会出现死等。

另外,PostgreSQL 下如果 schema 权限不对,引擎创建表时可能反复重试,也会表现为启动假死。我见过一个案例,GRANT USAGE忘了给,启动日志只留下一句“Unable to obtain connection from database”,排查半天才发现是权限问题。

建议 Flowable 独立连接池至少 10 起步,异步任务多的项目给到 20 也不过分。同时把 HikariCP 的pool-name分别命名,启动时看到BusinessPoolFlowablePool各自 Start completed,就能确认两个连接池都起来了。

5. 日常维护与性能优化建议

5.1 独立连接池参数怎么给

多数据源配置完成只是开始,连接池参数直接影响引擎稳定性。我的经验是 Flowable 连接池不能照抄业务连接池,因为它有异步执行器,工作线程数量和数据库连接数强相关。

参数建议值说明
maximum-pool-size10 ~ 20异步执行器线程数 + 预留余量
minimum-idle2 ~ 5连接数超过活跃数较多时,可以设小减少空闲占用
connection-timeout3000 ~ 5000取连接等待上限,任务量大时避免线程无限等待
validation-timeout1000 ~ 3000连接校验超时,PG 下建议配合connection-test-query
pool-name自定义区分日志,方便观察哪个连接池出问题

Flowable 异步执行器的线程配置一般不用动,但如果项目里定时流程任务特别多,可以调整:

spring: flowable: async-executor-core-pool-size: 8 async-executor-max-pool-size: 16 async-executor-keep-alive-time: 30

注意async-executor-core-pool-size和连接池maximum-pool-size之间要有合理的比例关系,线程数多于连接数时,多出来的线程都在等待拿连接。

5.2 历史数据增长与清理

流程引擎跑久了,ACT_HI_ACTINSTACT_HI_TASKINSTACT_HI_PROCINST这几张历史表的增长速度会超出预期。如果你的业务并不需要完整的过程审计,history-level没必要设成fullaudit一般就够用了。

如果历史数据已经很大,可以用定时任务按条件清理,但要注意删除顺序,先删子表再删主表。示例 SQL:

DELETE FROM act_hi_actinst WHERE proc_inst_id_ IN ( SELECT id_ FROM act_hi_procinst WHERE start_time_ < now() - interval '180 days' ); DELETE FROM act_hi_taskinst WHERE proc_inst_id_ IN ( SELECT id_ FROM act_hi_procinst WHERE start_time_ < now() - interval '180 days' ); DELETE FROM act_hi_procinst WHERE start_time_ < now() - interval '180 days';

这类清理建议在业务低峰期执行,删除大量记录时注意控制批次,避免把流程库的 WAL 撑爆。

5.3 备份、监控和发布注意事项

多数据源隔离的好处,在做备份和监控时体现得最明显。PostgreSQL 下只备份流程 schema:

pg_dump -h host -p 5432 -U flow_user -d business_db -n flowable -F c -f flowable_backup.dump

MySQL 下直接指定库名:

mysqldump -h host -u flow_user -p flowable_db > flowable_backup.sql

监控方面重点关注三件事:ACT_RU_EXECUTION有没有异常积压的未完成流程、ACT_RU_JOB里错误重试的任务数量、以及连接池活跃连接数曲线。这几个指标能提前暴露流程引擎的大多数问题。

发布的时候还有个细节:业务系统发版时,尽量让 Flowable 引擎的database-schema-update保持稳定,不要在测试环境开true、生产环境设false,两套配置不一致,很容易造成“测试好好的,生产缺字段”的尴尬。引擎版本升级要单独排期,先备份,再执行升级脚本,最后替换依赖发版。

回到开头说的那个项目,折腾完这轮多数据源配置,我最大的体会是:Flowable 多数据源本身不难,难的是把“数据源”、“事务管理器”、“Schema”这三件事绑定在一起。大部分报错看起来像玄学,其实是配置对象之间没有对上号。如果你正卡在类似问题上,优先检查三件事:引擎到底用了哪个 DataSource、哪个 TransactionManager、databaseSchema是不是为空。把这三个值打印出来,问题基本就摊在桌面上了。项目里如果还有第二套 Flowable 环境或者流程引擎将来要拆分出去,这套配置思路也能直接复用,无非是多加一组数据源配置,把 schema 再拆一个出来而已。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 0:34:18

3天搞定赤峰建设业协会的官方网站从零搭建

3天搞定赤峰建设业协会的官方网站从零搭建 备案流程一头雾水?这是很多协会、企业建站时最头疼的坎。别慌,我从零搭建过上百个类似站点,深知这里的弯弯绕绕。今天就把赤峰建设业协会的官方网站建设过程拆开揉碎讲给你听。 为什么备案成了第一道坎?…

作者头像 李华
网站建设 2026/9/16 0:29:54

避开模板坑,赤峰建设业协会的官方网站保姆级建站教程

避开模板坑,赤峰建设业协会的官方网站保姆级建站教程 很多搞建筑行业的老板,一提到官网就头疼。之前花了几千块找个外包,做出来全是那些烂大街的模板,大红大绿,字体乱飞,客户一看就觉得不专业。更别提那些“智能识别”功能,点进去全是加载不出来的广告。 模板网站太丑不够用…

作者头像 李华
网站建设 2026/9/16 0:23:58

JavaScript对象核心概念与高级特性详解

1. JavaScript对象基础概念JavaScript中的对象是这门语言最核心的概念之一&#xff0c;也是构建复杂应用的基础。简单来说&#xff0c;对象就是一组属性的集合&#xff0c;每个属性由键值对(key-value)组成。在ES6之前&#xff0c;我们主要通过构造函数和原型链来实现面向对象编…

作者头像 李华
网站建设 2026/9/16 0:23:19

3个真实案例复盘wordpress中函数get安全漏洞修复与注意事项

3个真实案例复盘wordpress中函数get安全漏洞修复与注意事项 上周凌晨两点,手机突然疯狂震动。不是骚扰电话,是服务器监控报警。我睁开眼一看,心里“咯噔”一下:某客户的企业官网首页源码被篡改,插进了一段看不懂的JS代码。这就是典型的 网站被黑挂马…

作者头像 李华
网站建设 2026/9/16 0:19:24

微信好友恢复功能解析与安全使用指南

1. 微信好友恢复功能的真实性与现状微信作为国内最大的社交应用&#xff0c;其功能迭代和隐藏特性一直是用户关注的焦点。最近网络上流传的"微信隐藏好友恢复功能"引起了广泛讨论&#xff0c;但实际情况可能与部分用户的期待有所出入。首先需要明确的是&#xff0c;微…

作者头像 李华
网站建设 2026/9/16 0:19:23

基于时频脊线的跳频信号参数估计与MATLAB实现

简介&#xff1a;面向跳频信号参数估计这一典型信号处理任务&#xff0c;提供了一套基于时频脊线提取的MATLAB实现方案&#xff0c;适合电子信息工程、计算机、数学等专业学生用于课程设计、期末大作业与毕业设计。代码整体采用参数化编程思路&#xff0c;跳频频率、采样率等关…

作者头像 李华