转载至: https://blog.csdn.net/wo541075754/article/details/75201934
no-loop
定义当前的规则是否不允许多次循环执行, 默认是 false, 也就是当前的规则只要满足条件, 可以无限次执行. 什么情况下会出现规则被多次重复执行呢? 下面看一个实例:
- package com.rules
- import com.secbro.drools.model.Product;
- rule updateDistcount
- no-loop false
- when
- productObj:Product(discount> 0);
- then
- productObj.setDiscount(productObj.getDiscount() + 1);
- System.out.println(productObj.getDiscount());
- update(productObj);
- end
- View Code
其中 Product 对象的 discount 属性值默认为 1. 执行此条规则时就会发现程序进入了死循环. 也就是说对传入当前 workingMemory 中的 FACT 对象的属性进行修改, 并调用 update 方法就会重新触发规则. 从打印的结果来看, update 之后被修改的数据已经生效, 在重新执行规则时并未被重置. 当然对 Fact 对象数据的修改并不是一定需要调用 update 才可以生效, 简单的使用 set 方法设置就可以完成, 但仅仅调用 set 方法时并不会重新触发规则. 所以, 对 insert,retract,update 方法使用时一定要慎重, 否则极可能会造成死循环.
可以通过设置 no-loop 为 true 来避免规则的重新触发, 同时, 如果本身的 RHS 部分有 insert,retract,update 等触发规则重新执行的操作, 也不会再次执行当前规则.
上面的设置虽然解决了当前规则的不会被重复执行, 但其他规则还是会收到影响, 比如下面的例子:
- package com.rules
- import com.secbro.drools.model.Product;
- rule updateDistcount
- no-loop true
- when
- productObj:Product(discount> 0);
- then
- productObj.setDiscount(productObj.getDiscount() + 1);
- System.out.println(productObj.getDiscount());
- update(productObj);
- end
- rule otherRule
- when
- productObj : Product(discount> 1);
- then
- System.out.println("被触发了" + productObj.getDiscount());
- end
- View Code
此时执行会发现, 当第一个规则执行 update 方法之后, 规则 otherRule 也会被触发执行. 如果注释掉 update 方法, 规则 otherRule 则不会被触发. 那么, 这个问题是不是就没办法解决了? 当然可以, 那就是引入 lock-on-active true 属性.
来源: http://www.bubuko.com/infodetail-2718260.html