规则属性
1.no-loop
默认值:false
类型:Boolean
说明:防止死循环,当规则通过类似update这样的函数修改了Fact对象时,可以会使规则再次被激活,从而导致死循环。设置no-loop为true可以避免当前规则then部分被修改后的Fact对象再次被激活。从而防止死循环的发生。
规则内容:
1 rule "testNoLoop1" 2 when 3 $p:Person(age == 30); 4 then 5 $p.setAge("30"); 6 update($p); 7 System.out.println("testNoLoop1 不设置 no-loop时的效果"); 8 end
配置文件内容:
1 <kbase name="isNoLoop" packages="rules.testNoLoop"> 2 <ksession name="isNoLoop"/> 3 </kbase>
Java调用代码:
1 @Test 2 public void testNoLoop1() { 3 KieSession ks = kc.newKieSession("isNoLoop"); 4 Person person = new Person(); 5 person.setName("张三"); 6 person.setAge("30"); 7 person.setClassName("一班"); 8 ks.insert(person); 9 int count = ks.fireAllRules(); 10 System.out.println("总执行了" + count + "条规则"); 11 ks.dispose(); 12 }
结果:
testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果 testNoLoop1 不设置 no-loop时的效果
出现了死循环,重新修改规则内容:
1 rule "testNoLoop2" 2 no-loop true 3 when 4 $p:Person(age == 30); 5 then 6 $p.setAge("30"); 7 update($p); 8 System.out.println("testNoLoop1 不设置 no-loop时的效果"); 9 10 end
使用no-loop true的结果:
1 2019-08-03 14:58:01 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES 2 testNoLoop1 设置 no-loop时的效果 3 2019-08-03 14:58:01 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING 4 2019-08-03 14:58:01 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE 5 总执行了1条规则 6 2019-08-03 14:58:01 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED
继续修改规则内容:
1 rule "testNoLoop3" 2 no-loop true 3 when 4 $p:Person(name == "张三"); 5 then 6 $p.setAge("30"); 7 update($p); 8 System.out.println("testNoLoop3 设置 no-loop时的效果"); 9 10 end 11 12 rule "testNoLoop4" 13 no-loop true 14 when 15 $p:Person(age == 30); 16 then 17 $p.setName("张三"); 18 update($p); 19 System.out.println("testNoLoop4 设置 no-loop时的效果"); 20 21 end
结果:
1 testNoLoop3 设置 no-loop时的效果 2 testNoLoop4 设置 no-loop时的效果 3 testNoLoop3 设置 no-loop时的效果 4 testNoLoop4 设置 no-loop时的效果 5 testNoLoop3 设置 no-loop时的效果 6 testNoLoop4 设置 no-loop时的效果 7 testNoLoop3 设置 no-loop时的效果 8 testNoLoop4 设置 no-loop时的效果 9 testNoLoop3 设置 no-loop时的效果 10 testNoLoop4 设置 no-loop时的效果 11 testNoLoop3 设置 no-loop时的效果 12 testNoLoop4 设置 no-loop时的效果 13 testNoLoop3 设置 no-loop时的效果 14 testNoLoop4 设置 no-loop时的效果 15 testNoLoop3 设置 no-loop时的效果 16 testNoLoop4 设置 no-loop时的效果
说明:从以上结果看出:只有在事实对象发生了变化时,才会出现死循环。如果在LHS部分的比较值不是update修改的值,会不会有问题呢?
继续修改规则内容:
1 rule "testNoLoop5" 2 // no-loop true 3 when 4 $p:Person(name == "张三"); 5 then 6 $p.setAge("30"); 7 update($p); 8 System.out.println("testNoLoop5 没有设置 no-loop时的效果"); 9 10 end
结果:
1 2019-08-03 15:11:32 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES 2 testNoLoop5 没有设置 no-loop时的效果 3 2019-08-03 15:11:32 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING 4 2019-08-03 15:11:32 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE 5 总执行了1条规则 6 2019-08-03 15:11:32 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED
没有死循环,继续修改规则内容:
1 testNoLoop6 没有设置 no-loop时的效果 2 testNoLoop6 没有设置 no-loop时的效果 3 testNoLoop6 没有设置 no-loop时的效果 4 testNoLoop6 没有设置 no-loop时的效果 5 testNoLoop6 没有设置 no-loop时的效果 6 testNoLoop6 没有设置 no-loop时的效果 7 testNoLoop6 没有设置 no-loop时的效果 8 testNoLoop6 没有设置 no-loop时的效果 9 testNoLoop6 没有设置 no-loop时的效果 10 testNoLoop6 没有设置 no-loop时的效果 11 testNoLoop6 没有设置 no-loop时的效果 12 testNoLoop6 没有设置 no-loop时的效果
在一个规则文件中,一个事实对象通过Drools函数被修改了,规则体将被再次激活。前提条件是被修改的对象与规则LHS部分的约束条件有一种包含的关系。导致了规则重新被激活和匹配。
原文:https://www.cnblogs.com/sunl123/p/11294945.html