为什么Drools持久化会话重载后会重新触发已匹配过的规则?
问题根因
你的假设没有错误,Drools持久化会话设计上确实需要恢复上一次运行的全量状态,出现重复触发是配置缺失和规则特性共同导致的,常见原因如下:
- 已执行激活记录默认不持久化
Drools 7.x版本默认仅持久化工作内存的事实、会话元数据、议程中待执行的激活,已经执行完成的规则激活状态不会持久化到存储,你需要手动开启激活持久化配置:在创建KieSession的配置类中添加如下参数:
kieSessionConfiguration.setProperty("drools.persistence.persistentActivations", "true");
开启后规则的已执行匹配记录会和会话一起持久化,恢复后不会重复触发。
- 规则未做幂等判断
默认规则只要匹配到符合条件的事实就会触发,如果你不想依赖Drools的激活持久化能力,更稳妥的方案是给规则增加幂等判断逻辑,比如给MyEvent增加processed布尔字段,修改规则如下:
package rules dialect "mvel" declare MyEvent @role( event ) @expires( 2d ) id String value: Double processed: boolean = false end rule "My Rule" when $event: MyEvent(processed == false, $value : value) then System.out.println("My event with value: " + $value); modify($event) { setProcessed(true) } end
这种方式不依赖框架的持久化特性,兼容性更强,也能避免后续规则调整带来的重复触发问题。
- 持久化基础配置缺失
确认你初始化KieEnvironment时已经正确传入了JPA实体管理器和事务管理器,Drools持久化依赖JPA实现状态存储,如果事务配置错误会导致部分状态未持久化。
额外注意事项
你使用的是CEP事件类型,配置了2天的过期时间,开启激活持久化后,事件过期时对应的激活记录也会自动清理,不会占用过多存储。
内容的提问来源于stack exchange,提问作者sedabrin
相关产品推荐
相关产品推荐

