gpt4 book ai didi

spring - 持久感知 KieSession 在事务期间不使用悲观锁

转载 作者:行者123 更新时间:2023-12-04 13:28:07 27 4
gpt4 key购买 nike

我正在使用 流口水 Spring Boot 2.3 和我已经实现了持久感知 KieSession ,其中 MySQL 用于存储 session 。我已经成功集成了默认EntityManagerFactory使用 Drools 的 Spring Boot,但我的问题是事务。默认情况下,Drools 在事务期间使用乐观锁,但它也允许我们使用悲观锁,这正是我想要的。现在,在触发规则时,Drools 使用以下查询持久/更新 MySQL 中的 KieSession:

update SessionInfo set lastModificationDate=?, rulesByteArray=?, startDate=?, OPTLOCK=? where id=? and OPTLOCK=?
现在,如果我不使用使用 @Transactional 的事务,上述语句将执行两次。方法中的注解,如果 @Transactional使用,则上述语句在触发规则后仅执行一次。
现在,如果我手动更改 OPTLOCK 字段的值,那么 Drools 会抛出异常:
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。可以在 this GitHub project 中查看整个堆栈跟踪.
我不确定 Drools 是否使用了环境中定义的悲观锁。关于我的 session 实现,我想要一个 KieSession因为我使用 KieSession 作为 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;
}
}
Controller 类:
@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 依赖项:
        <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>
代码实现也可以在 this GitHub Project中找到.任何形式的帮助/建议将不胜感激。谢谢你。

最佳答案

悲观锁只在 JBPM 中实现见 here
Drools 持久化中没有这样的功能,SessionInfo 将始终使用基于 JPA 的 @Version 注释的 OptimisticLocking。
如果您需要此类功能,请在 Drools 的 Jira 上提交功能请求

关于spring - 持久感知 KieSession 在事务期间不使用悲观锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66841081/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com