You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kie Persistence中实现JBoss事务管理?求生产可用示例

JBoss Transaction Manager for KiePersistence (Production-Grade Implementation)

I totally get why you’d want to switch from Bitronix to JBoss Transaction Manager (Narayana) for production—Drools docs are right that Bitronix is more suited for testing. Let’s walk through a complete, production-ready setup step by step.

1. Add Maven Dependencies

First, update your pom.xml to include the required Narayana and Drools persistence libraries. These pull in the production-grade transaction manager and seamless integration with KiePersistence:

<dependencies>
    <!-- JBoss Transaction API -->
    <dependency>
        <groupId>org.jboss.spec.javax.transaction</groupId>
        <artifactId>jboss-transaction-api_2.0_spec</artifactId>
        <version>1.0.1.Final</version>
    </dependency>
    <!-- Narayana Transaction Manager -->
    <dependency>
        <groupId>org.jboss.narayana.jta</groupId>
        <artifactId>narayana-jta</artifactId>
        <version>5.12.0.Final</version>
    </dependency>
    <!-- Drools Kie Persistence -->
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>kie-persistence-jpa</artifactId>
        <version>7.74.0.Final</version>
    </dependency>
    <!-- JPA Provider (Hibernate example) -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.14.Final</version>
    </dependency>
    <!-- Database Driver (MySQL example) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
</dependencies>

2. Configure JBoss Transaction Manager & DataSource

Next, set up the transaction manager and a managed data source. Here’s a reusable Java configuration class (works for both Spring and plain Java SE):

import org.jboss.narayana.jta.UserTransaction;
import org.jboss.narayana.jta.UserTransactionImp;
import org.jboss.narayana.txframework.api.configuration.transaction.TransactionManager;
import org.jboss.narayana.txframework.api.configuration.transaction.TransactionManagerImp;
import javax.sql.DataSource;
import com.mysql.cj.jdbc.MysqlDataSource;

public class JBossTMConfig {

    public static DataSource getDataSource() {
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setURL("jdbc:mysql://localhost:3306/kie_db?useSSL=false");
        dataSource.setUser("db_user");
        dataSource.setPassword("db_password");
        // Production-focused settings
        dataSource.setInitialSize(10);
        dataSource.setMaxTotal(50);
        dataSource.setMaxWaitMillis(3000);
        return dataSource;
    }

    public static UserTransaction getUserTransaction() {
        return new UserTransactionImp();
    }

    public static TransactionManager getTransactionManager() {
        return TransactionManagerImp.getTransactionManager();
    }
}

3. Initialize KieSession with Persistence & JBoss TM

Now wire up the KieSession to use JBoss transactions for persistence. This example uses JPA (required for KiePersistence):

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.EnvironmentName;
import org.kie.internal.persistence.jpa.JPAKnowledgeService;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class KiePersistenceSetup {

    public static KieSession createPersistentKieSession() {
        // Initialize JPA EntityManagerFactory (matches persistence.xml)
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("kie-persistence-unit");

        // Set up environment with JBoss TM and EMF
        Environment env = KieServices.Factory.get().newEnvironment();
        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
        env.set(EnvironmentName.TRANSACTION_MANAGER, JBossTMConfig.getTransactionManager());
        env.set(EnvironmentName.DATASOURCE, JBossTMConfig.getDataSource());

        // Load KieContainer from your kmodule.xml
        KieContainer kieContainer = KieServices.Factory.get().getKieClasspathContainer();

        // Create persistent KieSession (JTA transaction-aware)
        return JPAKnowledgeService.newStatefulKnowledgeSession(
                kieContainer.getKieBase("myKieBase"),
                null,
                env
        );
    }
}

Don’t forget your persistence.xml (place in src/main/resources/META-INF/):

<persistence-unit name="kie-persistence-unit" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:/MySqlDS</jta-data-source>
    <class>org.drools.persistence.info.SessionInfo</class>
    <class>org.drools.persistence.info.WorkItemInfo</class>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
        <property name="hibernate.hbm2ddl.auto" value="update"/>
        <property name="hibernate.show_sql" value="false"/>
        <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
    </properties>
</persistence-unit>

4. Execute Rules with Transaction Management

Finally, wrap rule execution in a transaction to ensure atomic persistence:

import org.kie.api.runtime.KieSession;
import javax.transaction.UserTransaction;

public class RuleExecutor {

    public static void executeRulesWithTransaction() {
        UserTransaction ut = JBossTMConfig.getUserTransaction();
        KieSession ksession = null;

        try {
            ut.begin();
            ut.setTransactionTimeout(30); // Prevent long-running transactions

            ksession = KiePersistenceSetup.createPersistentKieSession();
            // Insert your business facts
            ksession.insert(new Order("ORD-123", 100.0));
            // Fire rules
            ksession.fireAllRules();

            ut.commit();
            System.out.println("Rules executed and session persisted successfully");
        } catch (Exception e) {
            try {
                if (ut != null) ut.rollback();
                System.err.println("Transaction rolled back due to error: " + e.getMessage());
            } catch (Exception rollbackEx) {
                rollbackEx.printStackTrace();
            }
        } finally {
            if (ksession != null) {
                ksession.dispose();
            }
        }
    }

    public static void main(String[] args) {
        executeRulesWithTransaction();
    }
}

// Example fact class (must be serializable for persistence)
class Order implements java.io.Serializable {
    private String orderId;
    private double amount;

    public Order(String orderId, double amount) {
        this.orderId = orderId;
        this.amount = amount;
    }

    // Getters/setters omitted for brevity
}

Production Tips

  • Tune Data Source: Adjust connection pool sizes, timeouts, and validation settings based on your actual workload.
  • Monitoring: Use Narayana’s built-in JMX endpoints or tools like Prometheus to track transaction performance and status.
  • Serialization: Ensure all facts inserted into the KieSession implement java.io.Serializable—required for persistent sessions.
  • Error Handling: Add retry logic for transient database errors to improve resilience.

内容的提问来源于stack exchange,提问作者Prog_G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:56:31