jboss drools,多个相同的事实,消防规则只有一次

时间:2014-07-14 11:29:22

标签: drools

我想执行我的规则,我的java代码如下:

Fact fact1 = new Fact(); 
fact1.setName("name1"); 
fact1.setValue("chn"); 
.... 

Fact fact2 = new Fact(); 
fact2.setName("name2"); 
fact2.setValue("chn"); 
.... 

List<Fact> facts = new ArrayList<Fact>(); 
facts.add(fact1); 
facts.add(fact2); 

ksession.execute(facts); 

my rules like : 

rule "rule1" 
    when 
        $partFact:Fact(value=="chn") 
    then 
        Action action = new Action(); 
        .... 
end 

rule "rule2" 
    when 
        $partFact:Fact(name=="name1") 
    then 
        Action action = new Action(); 
        .... 
end 

我想要的是:

  1. rule1和rule2只执行了一条规则,即如果规则1&#39;执行,然后&#39; rule2&#39;甚至没有遇到过规则2&#39;条件。

  2. 每个规则只执行一次,例如,有2个事实,所有这2个事实满足&#39; rule1&#39;,但&#39; rule1&#39;只执行一次,而不是2次。

  3. 我如何实现目标? 提前谢谢。

3 个答案:

答案 0 :(得分:2)

试试这些:

rule "rule1" 
    when 
        exists Fact(value=="chn") 
    then 
        Action action = new Action(); 
        .... 
end 

rule "rule2" 
    when
        not Fact(value=="chn")
        exists Fact(name=="name1") 
    then 
        Action action = new Action(); 
        .... 
end 

答案 1 :(得分:0)

您可以使用&#34; NO-LOOP&#34;属性。使用&#34; no-loop&#34;对于每组事实的属性,规则只触发一次,但限制是如果您将修改任何其他规则组中的事实,那么这些规则将再次处于活动状态。

您可以尝试的一个解决方案是&#34;锁定活动&#34;属性以避免涉及一个或多个规则的无限执行循环。 lock-on-active是一种无循环的更新。

锁定活动由规则组确定范围,并且只要该组被聚焦,就会阻止规则重新启动。它不依赖于新事实或对现有事实的更新,而只取决于议程重点。如果您不操纵组,这可能是一个选项。

答案 2 :(得分:-2)

阻止其他规则执行的一条规则可能是沉默异常的症状。 将规则执行包装到catch子句中。我调试了一个规则执行阻止其他规则被执行的情况,但这是因为某些事情在规则执行中抛出,异常停止了规则执行链,并且异常被捕获到代码中的其他地方。长话短说,孤立执行:

try {
    kieSession.fireAllRules();
} catch (Exception e) {
    LOGGER.error("Error on rules execution", e);
    ... re-throw or manage the exception
} 

这个错误很明显。在运行规则时,我们不得不期待异常!