81.2. 有状态 KIE 会话


有状态 KIE 会话是一种会话,用于随着时间的推移对事实进行迭代更改。在有状态 KIE 会话中,来自之前调用 KIE 会话(之前会话状态)的数据会在会话调用之间保留,而在无状态 KIE 会话中,数据会被丢弃。

警告

确保在运行有状态 KIE 会话后调用 dispose() 方法,以便在会话调用之间不会发生内存泄漏。

有状态 KIE 会话通常用于以下用例:

  • 监控 (如监控库存市场并自动化购买流程)
  • 诊断,如运行故障查找进程或医疗诊断流程
  • 物流,如 parcel 跟踪和交付配置
  • 确保合规性,如验证市场交易的合法性

例如,请考虑以下触发警报数据模型和示例 DRL 规则:

sprinklers 和触发警报的数据模型

public class Room {
  private String name;
  // Getter and setter methods
}

public class Sprinkler {
  private Room room;
  private boolean on;
  // Getter and setter methods
}

public class Fire {
  private Room room;
  // Getter and setter methods
}

public class Alarm { }
Copy to Clipboard Toggle word wrap

激活 sprinklers 和 alarm 设置的 DRL 规则示例

rule "When there is a fire turn on the sprinkler"
when
  Fire($room : room)
  $sprinkler : Sprinkler(room == $room, on == false)
then
  modify($sprinkler) { setOn(true) };
  System.out.println("Turn on the sprinkler for room "+$room.getName());
end

rule "Raise the alarm when we have one or more fires"
when
    exists Fire()
then
    insert( new Alarm() );
    System.out.println( "Raise the alarm" );
end

rule "Cancel the alarm when all the fires have gone"
when
    not Fire()
    $alarm : Alarm()
then
    delete( $alarm );
    System.out.println( "Cancel the alarm" );
end


rule "Status output when things are ok"
when
    not Alarm()
    not Sprinkler( on == true )
then
    System.out.println( "Everything is ok" );
end
Copy to Clipboard Toggle word wrap

对于 当一个触发时,触发了 sprinkler 规则,在发生触发时,会为使用该房间创建 Fire 类的实例并插入到 KIE 会话中。该规则为 Fire 实例中匹配特定 空间 添加约束,以便只检查该空间的 sprinkler。执行此规则时,sprinkler 激活。其他示例规则决定了警报何时激活或相应地取消激活。

无状态 KIE 会话依赖于标准 Java 语法来修改字段,有状态 KIE 会话依赖于规则中的修改语句来通知更改的决策引擎。然后,决策引擎会超出变化的原因,并评估对后续规则执行的影响。这个过程是决策引擎使用差异和 真相维护 的一部分,在有状态 KIE 会话中至关重要。

在本例中,Red Hat Decision Manager 项目的 ~/resources 文件夹中的示例规则和所有其他文件都是使用以下代码构建:

创建 KIE 容器

KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
Copy to Clipboard Toggle word wrap

此代码编译类路径上找到的所有规则文件,并在 KieContainer 中添加了此编译结果(即 KieModule 对象)。

最后,KieSession 对象从 KieContainer 进行实例化,并针对指定数据执行:

实例化有状态 KIE 会话并输入数据

KieSession ksession = kContainer.newKieSession();

String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"};
Map<String,Room> name2room = new HashMap<String,Room>();
for( String name: names ){
    Room room = new Room( name );
    name2room.put( name, room );
    ksession.insert( room );
    Sprinkler sprinkler = new Sprinkler( room );
    ksession.insert( sprinkler );
}

ksession.fireAllRules();
Copy to Clipboard Toggle word wrap

控制台输出

> Everything is ok
Copy to Clipboard Toggle word wrap

添加数据后,决策引擎会完成所有模式匹配,但没有执行规则,因此会显示配置的验证消息。在新的数据触发规则条件时,决策引擎会执行规则来激活警报,然后取消已激活的警报:

输入新数据来触发规则

Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );
Fire officeFire = new Fire( name2room.get( "office" ) );

FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
FactHandle officeFireHandle = ksession.insert( officeFire );

ksession.fireAllRules();
Copy to Clipboard Toggle word wrap

控制台输出

> Raise the alarm
> Turn on the sprinkler for room kitchen
> Turn on the sprinkler for room office
Copy to Clipboard Toggle word wrap

ksession.delete( kitchenFireHandle );
ksession.delete( officeFireHandle );

ksession.fireAllRules();
Copy to Clipboard Toggle word wrap

控制台输出

> Cancel the alarm
> Turn off the sprinkler for room office
> Turn off the sprinkler for room kitchen
> Everything is ok
Copy to Clipboard Toggle word wrap

在本例中,为返回的 factHandle 对象保留一个引用。事实句柄是插入的实例的内部引擎引用,让实例被调整或修改。

如示例所示,来自之前有状态 KIE 会话(激活的警报)的数据和结果会影响随后的会话(alarm 取消)的调用。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat