共计 3477 个字符,预计需要花费 9 分钟才能阅读完成。
一、了解
在 drools
中存在 2 种 session,一种是有状态的 Session (Stateful Session
),另外一种一种是无状态的 Session (Stateless Session
)。
1、那么他们 2 者之间有什么不同呢?
2、何时该应用有状态的 Session,何时该应用无状态的 Session?此处简略说一下我的了解
。
1、有状态 Session
有状态 session 是应用推理对 fact 对象随工夫进行迭代更改的会话。 在有状态的 session 中,来自 session 的先前调用(先前的会话状态)的数据在会话调用之间保留,而在无状态的 session 中,该数据被抛弃。
2、无状态 Session
无状态 session 是不会应用推理对 fact 对象随工夫进行迭代更改的会话。 无状态 Session 的先前调用的数据在会话之间不会保留的。
解释:
针对 无状态 session 是不会应用推理对 fact 对象随工夫进行迭代更改的会话
的了解,我的了解是 针对Java Api
来应用的,
1、在无状态的 Session 中,只有 execute
办法,屡次调用 execute
办法,在上次 execute
办法不会影响下次 execute
办法的执行。
2、而在 drl
文件中应用 insert
或update
或 modify
或delete
等办法时,会导致工作内存的对象更新,导致规定的从新匹配。
3、那么何时应用不同的 Session 呢?
1、如果说咱们只是验证一下规定,那么用无状态的 Session。
比方:
- 验证用户是否有开银行卡的条件。
- 计算订单金额的折扣。
即一步就能够实现。
2、如果说咱们的规定须要多步来实现,则能够用有状态的 Session。
比方:
- 向 Session 中插入 Fact 对象 A,而后触发规定。
- 执行一段 Java 代码
- 向 Session 中插入 Fact 对象 B,而后触发规定,此时的规定须要依赖上一步规定的数据。
即须要关联的多步来实现。
二、需要
咱们本人有一个 Count
对象,该对象存在 cnt
和name
2 个属性。
规定文件中存在如下 2 个规定
规定一:
如果工作内存中存在 Count
对象,则将 Count
对象的 cnt
属性加 1
规定二:
如果工作内存中存在 2
个Count
对象,一个对象的 name=count-01
另一个对象的 name=count-02
则输入 ok
字符串。
针对有状态 Session 和无状态 Session,看后果有什么不同。
三、实现步骤
1、我的项目构造阐明
2、引入 jar 包
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>7.69.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
3、编写 Count 类
@Data
@AllArgsConstructor
public class Counter {
/**
* 名称
*/
private String name;
/**
* 计数
*/
private Integer cnt;
}
就是一个一般的 java 对象。
4、编写 kmodule.xml 文件
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kabse-01" packages="rules.stateful" default="false">
<!--
type="stateful" 示意有状态的 session
-->
<ksession name="stateful-session" default="false" type="stateful"/>
</kbase>
<kbase name="kabse-02" packages="rules.stateless" default="false">
<!--
type="stateless" 示意无状态的 session
-->
<ksession name="stateless-session" default="false" type="stateless"/>
</kbase>
</kmodule>
此处须要留神 ksession
中type
的值,无状态 Session 和有状态 Session 的值不统一,不写 type,默认就是有状态 Session。
5、编写规定文件
package rules.stateful
import com.huan.drools.Counter
// 将 counter 中的 cnt 的值递增一下
rule "stateful_rule_count_increment"
when
$counter: Counter( )
then
$counter.setCnt($counter.getCnt() + 1);
System.out.println("rule_count_increment: count name:[" + $counter.getName()+"],cnt=[" + $counter.getCnt() + "]");
end
// 如果工作内存中同时存在 count-01 和 counter-02 则输入 ok
rule "stateful_rule_count_exists"
when
Counter(name == "count-01") and Counter(name == "count-02")
then
System.out.println("ok");
end
6、Stateful session 运行后果
1、因为是有状态的 Session,在屡次 fireAllRules
的时候,上次插入到工作内存的对象还是存在的。即 Session 的数据保留了
。
2、有状态 Session 在执行完之后,必须要调用dispose
办法,防止内存透露。
7、Stateless Session 运行后果
无状态的 Session,因为会失落 Session 的数据,所以 ok
没有输入进去。
四、注意事项
1、在 drl
文件中,应用 insert\update\modify\delete
等办法时,都在导致规定的从新匹配。
2、Java
代码中是否能够获取 stateful session
或stateless session
是有 ksession
中的 type
的值决定的。
3、stateless session
在 execute
执行完之后,会革除工作内存中的数据,而 stateful session
在fireAllRules
则不会革除,除非调用了 dispose
办法。
4、集体了解有状态和无状态从 api 层面更好了解。
五、残缺代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-session
六、参考文档
1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#kie-sessions-con_decision-engine
2、https://www.javainuse.com/drools_states
3、https://groups.google.com/g/drools-usage/c/qYbqiS1ht4g