当前位置: 首页 > 知识库问答 >
问题:

drools中的无状态与有状态会话行为

郝昊天
2023-03-14

我对口水还不熟悉。我试图理解Drools提供的无状态会话和有状态会话之间的区别。

根据我的初步理解,

在无状态会话的情况下,如果在任何规则的操作执行过程中修改了事实,则不会将其重新提交给推理引擎以找出与修改后的事实匹配的新规则。

在状态会话的情况下,如果在任何规则的操作执行过程中修改了事实,则它将被重新提交给推理引擎以找出与修改后的事实相匹配的新规则,然后执行相应的操作。

因此,当我试图通过编写一个示例规则来验证这种行为时,我发现这两种情况下的行为完全相同。所以现在我对有状态会话和无状态会话之间的区别感到困惑。

我想请大家帮助我理解有状态和无状态会话的正确行为。

我正在粘贴有状态和无状态会话的示例代码及其输出和示例规则,以供参考。

licenseApplication.drl   (Rule file)

package com.idal.droolsapp

rule "Is of valid age"
    no-loop
when
    $a : Applicant( age < 18 )
then
    System.out.println( "Not eligible for license" );
    System.out.println( "Setting Valid to false" );
    modify( $a ) { setValid( false ) };
end

rule "Is of valid false"
    salience 100
when
    $a : Applicant( valid == false )
then
    System.out.println( "Second rule fired" );
end

输入对象(事实)申请人。Java语言

package com.idal.droolsapp;

public class Applicant {

    private String name;

    private int age;

    private boolean valid = true;

    public Applicant(String name, int age) {
        setName(name);
        setAge(age);
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public boolean isValid() {
        return valid;
    }

    @Override
    public String toString() {
        return "Applicant [name=" + name + ", age=" + age + ", valid=" + valid
                + "]";
    }


}

无状态会话示例。java(无状态会话测试代码)

package com.idal.droolsapp;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatelessKnowledgeSession;

public class StatelessSessionExample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                .newKnowledgeBuilder();

        kbuilder.add(ResourceFactory.newClassPathResource(
                "licenseApplication.drl", StatelessSessionExample.class),

        ResourceType.DRL);

        if (kbuilder.hasErrors()) {

            System.err.println(kbuilder.getErrors().toString());

        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

        Applicant applicant = new Applicant( "Mr John Smith", 16 );

        ksession.execute( applicant );

        System.out.println("Updated Applicant = " + applicant);
    }

}

无状态会话测试代码输出:

Not eligible for license
Setting Valid to false
Second rule fired
Updated Applicant = Applicant [name=Mr John Smith, age=16, valid=false]

StatefulSessionExample。java(无状态会话测试代码)

package com.idal.droolsapp;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class StatefulSessionExample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                .newKnowledgeBuilder();

        kbuilder.add(ResourceFactory.newClassPathResource(
                "licenseApplication.drl", StatefulSessionExample.class),

        ResourceType.DRL);

        if (kbuilder.hasErrors()) {

            System.err.println(kbuilder.getErrors().toString());

        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

        Applicant applicant = new Applicant( "Mr John Smith", 16 );

        ksession.insert( applicant );

        ksession.fireAllRules();

        ksession.dispose();

        System.out.println("Updated Applicant = " + applicant);
    }

}

状态会话测试代码输出:

Not eligible for license
Setting Valid to false
Second rule fired
Updated Applicant = Applicant [name=Mr John Smith, age=16, valid=false]

再次请大家帮助我理解有状态和无状态会话的正确行为。

提前谢谢你,曼尼什·甘地

共有1个答案

班玉堂
2023-03-14

据我所知,当您在无状态会话中触发规则时,更改不会触发新规则。但这并不意味着规则不会因为更改而被触发。第一条规则更改了有效的值,这意味着当您检查第二条规则的条件有效时,它已经为假,并且规则会触发。

如果更改影响了前一条规则的“何时”部分,则在无状态会话中,第一条规则不会再次触发,而在第一条规则中会再次触发。

 类似资料:
  • 需要一些帮助!!我对Drools中的有状态和无状态会话没有清晰的理解。我正在努力理解这一点,所以尝试了一个例子。 我在drools6.5版本上使用有状态和无状态会话测试了下面的drl,在这两种情况下都得到了相同的输出。根据我对无状态会话的理解,它应该只执行第一条规则,当应用程序对象在第一条规则中被修改时,第二条规则不应该被激活(“有效期”)。附加源代码。感谢您在这方面的帮助。

  • Drools中无状态会话和有状态会话的区别是什么。我浏览了不同的文件,发现下面 无状态会话执行规则时事实的任何更改都不会被规则引擎察觉,因此如果任何规则被修改,则不会发生其他规则的重新激活。 我试图执行下面的规则,发现了相同的结果

  • 我是EJB的新手,最近开始研究EJB(3.0)。我已经使用Java6年了,但以前从未使用过EJB。至少可以说,整个EJB业务的复杂性让我不知所措。我不明白我可以在哪里实际应用一些概念。 在理解无状态会话bean后,我想到的一个问题是,你能不能不要总是用一个没有本地成员的类的共享实例来替换无状态会话bean(实际上使其无状态)?我了解到正在为无状态会话bean进行实例池。如果没有状态,就不能简单地使

  • 如何为drools无状态会话设置全局变量。 假设两个线程访问同一个会话,但为每个线程设置一个全局变量customer arraylist和新的arraylist。对于全局变量customer,第二个线程的arraylist是否替换第一个线程的arraylist。 这似乎是Stateless知识库类留档的情况: 无状态KnowledgeSessions支持全局,其作用域有多种方式。我将首先介绍非命令

  • 对于有状态会话bean(SFSB)和无状态会话bean(SLSB)的用法,我有点困惑。 我知道SFSB与客户保持状态。这很有帮助:什么时候使用有状态会话bean而不是无状态会话bean? 这里和许多其他地方提供的示例是SFSB的购物车。 “如果一个任务需要一系列方法调用(不止一次),并且您需要保留以前的结果以在下一次调用中使用它们,那么就可以使用SFSB”--Source。这将更像是签出(页面之间

  • null null 如果进入房间的人是教师,则输入打印教师。 如果进入房间的人数超过30人,请通知我。 如果学生已上了超过20个小时的课,则更新状态为已完成。 现在我想要1和3组合在一起。 类似:4。如果有属性状态完成的学生进入教室,请通知老师。 现在,正如我前面所说的,这两个事件是分开的。所以在两个不同的规则中处理它更容易。但是当我想创建一个规则,它是规则4中1和3的组合,那么我必须验证一个进入