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

Drools 8中如何在BPMN流程的两个Rule Unit间共享DataStore

Drools 8 Rule Unit 跨单元共享 DataStore 实现方案

核心思路

Drools 8 中 Rule Unit 共享 DataStore 的本质是让多个 RuleUnitData 实例引用同一个 DataStore 对象,而非在每个类中单独声明新实例。借助 Quarkus/Kogito 的依赖注入能力,或者手动维护单例对象,就能实现跨单元的数据同步。

具体实现步骤

1. 定义共享数据模型

先确定需要跨单元共享的数据类型,比如示例中的Order对象:

public class Order {
    private String orderId;
    private boolean processedByA;
    // 省略 getter、setter 方法
}

2. 创建全局共享的 DataStore 实例

在 Quarkus 环境下,将 DataStore 封装为应用级单例,确保所有 RuleUnit 都能拿到同一个实例:

import org.drools.core.data.impl.TransactionalDataStore;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class SharedDataStores {
    private final DataStore<Order> sharedOrderStore = TransactionalDataStore.create();

    public DataStore<Order> getSharedOrderStore() {
        return sharedOrderStore;
    }
}

3. 实现 RuleUnitData 类

让 AUnit 和 BUnit 通过构造注入获取共享的 DataStore,不再在类内部单独声明:

import org.drools.ruleunits.api.DataStore;
import org.drools.ruleunits.api.RuleUnitData;
import jakarta.inject.Inject;

// AUnit 规则单元数据类
public class AUnit implements RuleUnitData {
    private final DataStore<Order> orders;

    @Inject
    public AUnit(SharedDataStores sharedDataStores) {
        this.orders = sharedDataStores.getSharedOrderStore();
    }

    public DataStore<Order> getOrders() {
        return orders;
    }
}

// BUnit 规则单元数据类
public class BUnit implements RuleUnitData {
    private final DataStore<Order> orders;

    @Inject
    public BUnit(SharedDataStores sharedDataStores) {
        this.orders = sharedDataStores.getSharedOrderStore();
    }

    public DataStore<Order> getOrders() {
        return orders;
    }
}

4. 编写规则与执行流程

在 DRL 文件中正常引用各自 RuleUnit 的 DataStore,底层共享实例会自动同步数据:

  • AUnit 规则文件(a-unit.drl):
package com.example.rules;

unit AUnit;

rule "Mark Order as Processed by A"
when
    $order: Order(processedByA == false) from orders
then
    modify($order) { setProcessedByA(true) };
end
  • BUnit 规则文件(b-unit.drl):
package com.example.rules;

unit BUnit;

rule "Process Order in B"
when
    $order: Order(processedByA == true) from orders
then
    System.out.println("Order " + $order.getOrderId() + " processed by B");
end

执行流程中,只需向共享 DataStore 插入数据,依次触发 A、B 单元即可:

import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
import org.drools.ruleunits.api.RuleUnitProvider;

@ApplicationScoped
public class RuleExecutor {
    @Inject
    private SharedDataStores sharedDataStores;

    public void executeFlow() {
        // 插入初始数据到共享DataStore
        Order order = new Order();
        order.setOrderId("ORD-001");
        sharedDataStores.getSharedOrderStore().add(order);

        // 执行A单元规则
        RuleUnitProvider.get().createRuleUnitInstance(new AUnit(sharedDataStores)).fire();

        // 执行B单元规则
        RuleUnitProvider.get().createRuleUnitInstance(new BUnit(sharedDataStores)).fire();
    }
}

关键注意点

  • 优先使用线程安全的 DataStore:Drools 提供的TransactionalDataStore本身支持线程安全,适合多单元并发场景。
  • 禁止在 RuleUnitData 内手动实例化 DataStore:必须保证所有单元引用同一个实例,否则无法实现数据共享。
  • 依赖注入简化管理:借助 Quarkus 的@ApplicationScoped注解,无需手动维护单例生命周期,降低出错概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:05:21