口水:无状态vs有状态知识会话



无状态和有状态知识会话的区别是什么?我读了一些文档,它们都是保持状态的。但是我什么时候可以使用无状态/有状态的知识会话。

无状态:在触发规则之前,将事实/工作记忆插入知识库会话。可以通过在执行规则时调用对象上的公共方法来设置这些事实,并且在设置这些对象后返回更改后的值。

在执行规则时对事实的任何更改,例如insert(xyz)modify(xyz),都不会被规则引擎察觉。

状态:在触发规则之前将事实/工作内存插入到知识库会话中,并且在触发规则之后必须调用dispose()以避免内存泄漏。

在执行规则(例如insert(xyz)modify(xyz))时对事实的任何更改都会被规则引擎感知。

无状态意味着为每个请求创建一个新的会话(因此不维护状态)。有状态意味着它将从前一个命令结束时会话的状态继续(例如,插入到会话中的所有数据仍将存在)。

我看到的基本区别是会话在无状态下自动处理的方式。选择一个或另一个并不会带来性能上的提升。实际上,无状态会话在其后面使用一个有状态会话。所以去想想吧!

我想在这里引用drools文档,它使我头脑清醒。

" statelessknowledgessession提供了一个方便的API,包装StatefulKnowledgeSession。它避免了调用dispose()的需要。无状态会话不支持迭代调用调用execute(…)是一个单次方法,它将在内部实例化一个statefulknowledgessession,添加所有用户数据和执行用户命令,调用fireAllRules,然后调用dispose()。"

所以基本上,无状态会话是使用一次的有状态会话。

这意味着无状态会话也可以做推理,不像这里的许多文档和一些答案所说的那样!这应该只取决于规则的"then"部分,不管你是否使用"modify"。

虽然我没有亲自验证,但这篇文章似乎支持我的推理。

https://groups.google.com/forum/!topic/drools-usage/qYbqiS1ht4g

在有状态会话中,即使在之前触发了规则之后,我们也可以修改事实并重新插入它们。

另一方面,在无状态会话中,一旦所有规则都被触发(使用execute()),我们就不能进一步修改事实并将它们重新插入会话中(因为在调用execution()后会话不可用)。

1)在无状态知识会话的情况下,当规则执行时,即一旦firerrules方法被调用,在插入的事实(在随后的部分)中的修改是不可用的规则引擎。在有状态知识会话的情况下,事实中的任何更改都可用于规则引擎。

2)一旦规则被触发,有状态知识会话对象必须调用dispose()方法来释放会话,避免内存泄漏。

3)在有状态知识会话的情况下,对事实的任何更改都可用于规则引擎。所以这些规则是迭代的。如果在DRL的最后一个规则中修改了事实A,则此更改将重新激活所有规则并触发基于事实A构建的规则。无状态知识会话不是这种情况。

隐藏的事实是无状态会话背后使用一个有状态会话

这个链接是准确的:https://groups.google.com/forum/#!主题/drools-usage/qYbqiS1ht4g口水应该加在正式文件里。

Stateful: "插入的数据对象将成为工作内存的一部分&可以在以后的规则执行中重用。"

无状态:"插入的数据对象在规则执行后将不存储在工作内存中"

如果我参考关于无状态会话的Drools文档,它说:

无状态KIE会话是不使用推理对事实随时间进行迭代更改的会话。在无状态KIE会话中,以前调用KIE会话的数据(以前的会话状态)在会话调用之间被丢弃,而在有状态KIE会话中,该数据被保留

这可能需要在文档中澄清,并将迭代替换为交互式

这并不意味着:

在执行规则时对事实的任何更改,例如insert(xyz)或modify(xyz),都不会被规则引擎察觉。

正如@Prakhyat在他的评论中建议的。

你实际上可以告诉Drools忽略任何更新(插入/修改)对工作内存进行更好的性能使用顺序模式在Phreak有更好的性能:

在顺序模式下,Drools引擎忽略规则中的任何插入、修改或更新语句,并以单个顺序执行规则。因此,在顺序模式下,规则执行可能会更快,但重要的更新可能不会应用到规则中。

顺序模式只适用于无状态的KIE会话

[…]

Drools引擎默认禁用顺序模式。

最新更新