我继承了一个程序,该程序使用drools api对定义的drl规则文件运行SettlementMessage对象。该程序在生产中一直运行约8年。现在,我们被要求从Solaris SunOS迁移到IBM AIX计算机,并开始看到一些不一致的结果,很少有规则将数量字段与值进行比较。
public class SettlementMessage implements Serializable {
private double Amount=0;
public double getAmount() {
return Amount;
}
public void setAmount(double amount) {
Amount = amount;
}
.....
}
产生不一致结果的规则定义如下:
rule "Settlement Rule 1.1 - Large Settlement Amount For JPY and HUF - External Group"
when
$message: SettlementMessage(amount > 100000000.00, currencyCode in ("JPY","HUF"), settlementMethod in ("DIRECT_DEBIT","SWIFT", "SWIFT_EREL"))
then
$message.setBusinessException("Exceeds Threshold - Confirm Settlement.");
end
rule "Settlement Rule 1.2 - Large Settlement Amount For Others - External Group"
when
$message: SettlementMessage(amount > 3000000.00, currencyCode not in ("JPY","HUF"), settlementMethod in ("DIRECT_DEBIT","SWIFT", "SWIFT_EREL"))
then
$message.setBusinessException("Exceeds Threshold - Confirm Settlement.");
end
还有许多其他规则,它们将SettlementMessage对象的不同属性与某些值进行匹配,并且所有规则都按预期工作。 我们只会看到这些规则匹配数量远低于定义阈值的对象的问题。
我们每天通过这些规则处理大量SettlementMessage
对象。通常,当系统日期提前时-我们将处理500到1500个SettlementMessage
对象。对象是按顺序而不是并行处理的。在大多数情况下,大多数对象将得到正确处理-如果数量低于指定的阈值,则规则不匹配。如果金额高于指定的阈值,则规则匹配。有时,某些对象会错误地与这些规则匹配(金额低于规则中定义的值阈值)。我们看到SettlementMessage
对象的示例的金额介于1到3000000之间,并且与其中一个规则匹配(取决于货币值)。
创建KieSession
并运行规则的Java程序打包为jar文件,并从Tibco Business Works适配器调用。 KieSession
对象创建为PooledObject
,并且在每个SettlementMessage
对象的多次调用之间重用。只要BW适应程序正在运行,KieSession
对象的生命就为PooledObject
。插入SettlementMessage
对象,调用fireAllRules
并删除SettlementMessage
对象。
一些有趣的发现:
当我们获得与这些规则不正确匹配的对象时,如果我再次重新发送相同的(克隆)SettlementMessage
对象,它将再次与该规则不正确地匹配。如果我重新启动BW适配器并再次重新发送相同的对象,则它将正确处理。就像KieSession
或基础决策表在内存中以某种方式损坏了,但是重新启动后一切恢复正常。
原始应用程序使用的是Drools 5.0.1 API,而我改写为使用Drools 7.12.0,这对行为没有影响。
有人知道为什么这个数量比较会在某些随机日期对某些对象不匹配吗?有没有办法修改此规则以完成相同的预期逻辑,但结果一致(没有不匹配)? 我尝试稍微更改这些规则的语法,但是没有运气解决我的问题。最大的问题是-对于我想尝试的每个更改,我都无法在DEV计算机上重现此问题,因此我需要在IBM AIX计算机上等待几天才能再次发生。
SunOS机器正在运行Oracle Java。
IBM AIX计算机正在运行Java IBM J9 VM 2.9。
对于如何重新制定此规则可能会对我所面临的问题产生某些影响的任何见解,我将不胜感激。