Drools规则执行异常:多Product对象时触发次数不符预期
问题分析与解决方案
你遇到的异常核心是第三条Drools规则的条件写法错误,导致了**交叉匹配(Cross Product)**问题,这就是规则触发次数随Product数量增加呈平方级增长的原因。
问题根源
先看你这条出问题的规则:
rule "Offer for Gold on Festival" when $productObject: Product(type == "gold") && Product(event == "sale") then $productObject.setDiscount($productObject.getDiscount() + 5); end
这里的&&连接了两个独立的Product模式,Drools会把所有满足type == "gold"的Product,和所有满足event == "sale"的Product进行两两组合匹配。而你的测试数据里每个Product同时满足这两个条件(type为gold、event为sale),所以:
- 1个Product时,匹配组合数是1×1=1次(符合预期)
- 2个Product时,匹配组合数是2×2=4次(对应每个对象触发2次这条规则)
- 3个Product时,匹配组合数是3×3=9次(对应每个对象触发3次这条规则)
再加上"Offer for Gold"规则每个对象触发1次,总次数就变成了2、6(2+4)、12(3+9),和你观察到的完全一致。
修正方案
你需要把两个条件合并到同一个Product模式中,确保规则只匹配同时满足两个条件的单个Product对象,而非交叉组合。修正后的规则可以写成两种形式:
形式一(推荐,更简洁)
rule "Offer for Gold on Festival" when $productObject: Product(type == "gold", event == "sale") then $productObject.setDiscount($productObject.getDiscount() + 5); end
形式二(保持&&写法)
rule "Offer for Gold on Festival" when $productObject: Product(type == "gold" && event == "sale") then $productObject.setDiscount($productObject.getDiscount() + 5); end
修正后的预期效果
- 传入1个Product:触发"Offer for Gold"和"Offer for Gold on Festival"各1次,共2次(符合预期)
- 传入2个Product:每个对象触发2条规则,总共4次(符合预期)
- 传入3个Product:每个对象触发2条规则,总共6次(符合预期)
另外,你给"Offer for Gold"设置的salience 1优先级是合理的,能确保先设置25的基础折扣,再叠加5的节日折扣,逻辑完全正确。
内容的提问来源于stack exchange,提问作者Count
相关产品推荐
相关产品推荐

