You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JBPM 7.74流程实例及KieSession持久化到数据库,实现Spring Boot启动时恢复

Spring Boot 3 + JBPM 7.74 持久化KieSession并恢复未完成流程实例

针对你在Spring Boot 3中嵌入JBPM 7.74,需要持久化KieSession到数据库并重启后恢复未完成流程的需求,以下是具体实现步骤:

1. 配置Maven依赖

确保你的pom.xml包含JBPM Spring Boot Starter、Spring Data JPA及数据库驱动:

<dependencies>
    <!-- JBPM Spring Boot Starter -->
    <dependency>
        <groupId>org.jbpm</groupId>
        <artifactId>jbpm-spring-boot-starter</artifactId>
        <version>7.74.0.Final</version>
    </dependency>
    <!-- Spring Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- MySQL驱动(根据你的数据库调整) -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2. 配置数据源与JBPM持久化

在application.properties中配置数据库连接及JBPM持久化参数:

# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/jbpm_db?useSSL=false&serverTimezone=UTC&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

# JBPM持久化配置
jbpm.persistence.enabled=true
jbpm.session.persistence.enabled=true
jbpm.persistence.dialect=org.hibernate.dialect.MySQL8Dialect

3. 创建持久化的StatefulKieSession

编写配置类生成支持持久化的KieSession(必须用StatefulKieSession,StatelessKieSession不支持持久化):

import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieSession;
import org.kie.internal.persistence.jpa.JPAKnowledgeService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import jakarta.persistence.EntityManagerFactory;

@Configuration
@EnableTransactionManagement
public class JbpmConfig {

    private final EntityManagerFactory entityManagerFactory;

    public JbpmConfig(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Bean
    public KieSession kieSession() {
        KieServices kieServices = KieServices.Factory.get();
        KieBase kieBase = kieServices.getKieClasspathContainer().getKieBase();
        
        // 构建持久化环境,绑定EntityManagerFactory和事务管理器
        var environment = new java.util.HashMap<String, Object>();
        environment.put(org.kie.api.runtime.EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
        environment.put(org.kie.api.runtime.EnvironmentName.TRANSACTION_MANAGER, org.springframework.transaction.support.TransactionSynchronizationManager.getResourceTransactionManager());
        
        // 创建持久化的StatefulKieSession
        KieSession kieSession = JPAKnowledgeService.newStatefulKnowledgeSession(kieBase, null, environment);
        
        // 注册工作项处理器(示例为人工任务处理器,根据你的流程调整)
        kieSession.getWorkItemManager().registerWorkItemHandler("Human Task", new org.jbpm.process.workitem.core.AbstractLogOrThrowWorkItemHandler());
        return kieSession;
    }
}

4. 启动流程实例(自动持久化)

在业务服务中注入KieSession,启动流程时添加@Transactional注解确保持久化生效:

import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.process.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ProcessService {

    private final KieSession kieSession;

    public ProcessService(KieSession kieSession) {
        this.kieSession = kieSession;
    }

    @Transactional
    public Long startProcess(String processId) {
        ProcessInstance processInstance = kieSession.startProcess(processId);
        // 流程实例启动后会自动持久化到数据库,返回实例ID用于后续操作
        return processInstance.getId();
    }
}

5. 应用重启后恢复未完成流程

编写恢复服务,在应用启动时加载所有未完成的流程实例:

import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.internal.persistence.jpa.JPAKnowledgeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.EntityManagerFactory;
import java.util.List;

@Service
public class ProcessRecoveryService {

    private final EntityManagerFactory entityManagerFactory;
    private final KieBase kieBase;

    public ProcessRecoveryService(EntityManagerFactory entityManagerFactory, KieBase kieBase) {
        this.entityManagerFactory = entityManagerFactory;
        this.kieBase = kieBase;
    }

    @Transactional
    public void recoverUnfinishedProcesses() {
        KieServices kieServices = KieServices.Factory.get();
        
        // 查询所有处于活跃状态的未完成流程实例
        List<Long> activeProcessIds = kieServices.getStoreServices()
                .findProcessInstances(null, List.of(ProcessInstance.STATE_ACTIVE), null, null)
                .stream()
                .map(ProcessInstance::getId)
                .toList();

        for (Long processId : activeProcessIds) {
            // 加载对应流程实例的KieSession
            var environment = new java.util.HashMap<String, Object>();
            environment.put(org.kie.api.runtime.EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
            environment.put(org.kie.api.runtime.EnvironmentName.TRANSACTION_MANAGER, org.springframework.transaction.support.TransactionSynchronizationManager.getResourceTransactionManager());

            KieSession kieSession = JPAKnowledgeService.loadStatefulKnowledgeSession(processId, kieBase, null, environment);
            
            // 若流程处于等待外部信号的状态,可在此触发信号继续执行
            // kieSession.signalEvent("triggerSignal", null);
        }
    }
}

在Spring Boot启动类中调用恢复方法:

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class JbpmApplication {

    public static void main(String[] args) {
        SpringApplication.run(JbpmApplication.class, args);
    }

    @Bean
    CommandLineRunner initRecovery(ProcessRecoveryService recoveryService) {
        return args -> recoveryService.recoverUnfinishedProcesses();
    }
}

关键注意事项

  • 所有操作流程的方法必须添加@Transactional,否则持久化操作不会提交到数据库
  • 确保数据库使用支持事务的存储引擎(如MySQL的InnoDB)
  • 首次启动后,可将spring.jpa.hibernate.ddl-auto改为validate,避免意外修改表结构
  • 若流程包含人工任务,JBPM会自动持久化任务数据,重启后可通过任务服务查询并继续处理
  • 不要使用StatelessKieSession,它仅支持一次性流程执行,不支持持久化和状态恢复

内容的提问来源于stack exchange,提问作者Ajinkya Khedkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:05:54