持久感知的KieSession在事务期间不使用悲观锁 [英] Persistent aware KieSession not using Pessimistic Lock during transactions

查看:66
本文介绍了持久感知的KieSession在事务期间不使用悲观锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Spring Boot 2.3中使用了 Drools ,并且实现了持久感知的 KieSession ,其中 MySQL 用于存储会话.我已经成功地将Spring Boot的默认 EntityManagerFactory 与Drools集成在一起,但是我的问题是事务.默认情况下,Drools在交易过程中使用乐观锁,但是它允许我们也使用悲观锁,这正是我想要的.现在,在触发规则时,Drools使用以下查询在MySQL中保持/更新KieSession:

I am using Drools with Spring Boot 2.3 and I have implemented the persistent aware KieSession, in which MySQL is used for storing the session. I have successfully integrated the default EntityManagerFactory of Spring Boot with Drools but my problem is with transactions. By default, Drools uses Optimistic Lock during transactions but it allows us to use the Pessimistic Lock as well, which is what I want. Now while firing rules, Drools persists/updates the KieSession in MySQL with the following query:

update SessionInfo set lastModificationDate=?, rulesByteArray=?, startDate=?, OPTLOCK=? where id=? and OPTLOCK=?

现在,如果我不使用方法中使用 @Transactional 批注的事务,并且使用了 @Transactional ,则上面的语句将执行两次.触发规则后仅执行一次.

Now the above statement is executed twice if I do not use transactions using the @Transactional annotation in the method, and if @Transactional is used then the above statement is executed only once after firing the rules.

现在,如果我手动更改OPTLOCK字段的值,则Drools会引发异常:

Now, if I manually change the value of the OPTLOCK field then Drools throws an exception:

javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [org.drools.persistence.info.SessionInfo#1]

其次:

Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [org.drools.persistence.info.SessionInfo#1]

由于此处的文本长度限制,我无法发布整个Stacktrace.可以在此GitHub项目中查看整个堆栈跟踪.

I am unable to post the entire Stacktrace due to text length limitations here. The entire stacktrace can be viewed in this GitHub project.

我不确定Drools是否正在使用环境中定义的悲观锁.关于我的会话实现,我想拥有一个 KieSession ,因为我将KieSession用作 Bean .

I am not sure whether Drools is using the Pessimistic Lock as defined in the environment. About my session implementation, I want to have a single KieSession since I am using KieSession as a Bean.

以下是我的实现:

配置类:

@Configuration
public class DynamicDroolsConfig {

    private KieServices kieServices;
    private KieFileSystem kieFileSystem;

    @Autowired
    private PersistentSessionDAO persistentSessionDAO;
    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;


    @PostConstruct
    private void init() {
        this.kieServices = KieServices.Factory.get();
        this.kieFileSystem = kieServices.newKieFileSystem();
    }

    @Bean
    public KieServices getKieServices() {
        return this.kieServices;
    }

    @Bean
    public KieContainer getKieContainer() {
        kieFileSystem.write(ResourceFactory.newClassPathResource("rules/rules.drl"));
        final KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kb = kieServices.newKieBuilder(kieFileSystem).buildAll();
        KieModule kieModule = kb.getKieModule();
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }

    @Bean
    public KieFileSystem getFileSystem() {
        return kieFileSystem;
    }

    @Bean
    public KieSession kieSession() {
        List<SessionInfo> sessionDetails = persistentSessionDAO.getSessionDetails();

        if (sessionDetails.size() == 0) {
            return kieServices.getStoreServices().newKieSession(getKieContainer().getKieBase(), null, getEnv());
        } else {
            return kieServices.getStoreServices().loadKieSession(sessionDetails.get(0).getId(), getKieContainer().getKieBase(), null, getEnv());
        }
    }

    private Environment getEnv() {
        Environment env = kieServices.newEnvironment();
        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
        env.set(EnvironmentName.TRANSACTION_MANAGER, platformTransactionManager);
        env.set(EnvironmentName.USE_PESSIMISTIC_LOCKING, true);
        env.set(EnvironmentName.USE_PESSIMISTIC_LOCKING_MODE, LockModeType.PESSIMISTIC_FORCE_INCREMENT.name());
        return env;
    }
}

控制器类:

@RestController
public class MyController {

    @Autowired
    private KieSession kieSession;

    @Transactional
    @GetMapping("fire-person")
    public void firePerson() {
        Person person = new Person();
        person.setName("Christy");
        kieSession.insert(person);
        kieSession.fireAllRules();
    }
}

事实类

public class Person implements Serializable {

    private String name;
    private int age;
    private String gender;
    private String toCompareName;
    private String toCompareGender;

    // getters and setters
}

存储库界面:

public interface DroolsSessionRepository extends JpaRepository<SessionInfo, Long> {
}

服务类别:

@Service
public class PersistentSessionDAO {

    @Autowired
    private DroolsSessionRepository droolsSessionRepository;

    public List<SessionInfo> getSessionDetails() {
        return droolsSessionRepository.findAll();
    }
}

亚军类:

@EntityScan(basePackages = {"com.sam.springdroolspersistence.entity", "org.drools.persistence.info"})
@EnableJpaRepositories
@SpringBootApplication
public class SpringDroolsPersistenceApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDroolsPersistenceApplication.class, args);
    }
}

使用的Drools依赖项:

The Drools dependencies used:

        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-persistence-jpa</artifactId>
            <version>${drools-version}</version>
        </dependency>

        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-spring</artifactId>
            <version>${drools-version}</version>
        </dependency>

        <dependency>
            <groupId>org.jbpm</groupId>
            <artifactId>jbpm-persistence-jpa</artifactId>
            <version>${drools-version}</version>
        </dependency>

代码实现也可以在此GitHub项目中找到.任何帮助/建议将不胜感激.谢谢.

The code implementation can also be found in this GitHub Project. Any kind of help/suggestions will be much appreciated. Thank you.

推荐答案

仅在JBPM中实现悲观锁定,请参见

Pessimistic locking is implemented only in JBPM see here

Drools持久性中没有此类功能, SessionInfo 将始终基于JPA的 @Version 批注使用OptimisticLocking.

There's no such functionality in Drools persistence, SessionInfo will always use OptimisticLocking based on JPA's @Version annotation.

如果您需要这样的功能,请在Drools的 Jira 中提出功能请求

If you need such feature, please file a feature request on Drools' Jira

这篇关于持久感知的KieSession在事务期间不使用悲观锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆