聊聊drools session的不同

一、理解

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文件中使用insertupdatemodifydelete等方法時,會導致工作內存的對象更新,導致規則的重新匹配。

3、那麼何時使用不同的Session呢?

1、如果說我們隻是驗證一下規則,那麼用無狀態的Session。
比如:

驗證用戶是否有開銀行卡的條件。計算訂單金額的折扣。

即一步就可以完成。

2、如果說我們的規則需要多步來完成,則可以用有狀態的Session。
比如:

向Session中插入Fact對象A,然後觸發規則。執行一段Java代碼向Session中插入Fact對象B,然後觸發規則,此時的規則需要依賴上一步規則的數據。

即需要關聯的多步來完成。

二、需求

我們自己有一個Count對象,該對象存在cntname2個屬性。
規則文件中存在如下2個規則

規則一:
如果工作內存中存在Count對象,則將Count對象的cnt屬性加1
規則二:
如果工作內存中存在2Count對象,一個對象的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>

此處需要註意ksessiontype的值,無狀態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 sessionstateless session是有ksession中的type的值決定的。
3、stateless sessionexecute執行完之後,會清除工作內存中的數據,而stateful sessionfireAllRules則不會清除,除非調用瞭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

到此這篇關於drools session理解的文章就介紹到這瞭,更多相關drools session內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: