Sod*_*ved 6 java mysql jpa mariadb spring-data-jpa
我认为这个问题类似于Database pessimistic locks with Spring data JPA (Hibernate under the hood),但我想我会单独问,因为不完全相同。
我在 mariadb 数据库之上有一个多线程/节点 springboot 应用程序,其表如下
CREATE TABLE job (
id INT PRIMARY KEY AUTO_INCREMENT,
owner VARCHAR(50),
status VARCHAR(10) );
Run Code Online (Sandbox Code Playgroud)
拥有一个Job如您所期望的域类。
有一个JobRepository扩展的接口CrudRepository<Job,Integer>和一个服务类。
应用程序规则是,如果所有者和状态值集相同,则我们无法插入新作业。例如,如果这是老式的本机 sql,我只会:
START TRANSACTION;
INSERT INTO job (owner, status)
SELECT 'fred', 'init' FROM DUAL
WHERE NOT EXISTS
( SELECT 1 FROM job
WHERE owner = 'fred' AND status IN ('init', 'running')
);
COMMIT;
Run Code Online (Sandbox Code Playgroud)
但如何在 JPA/CrudRepository 中执行此操作。
我分为数据库操作。定义了一个存储库方法:
@Lock(LockModeType.READ)
long countByOwnerAndStatusIn(String owner, List<String> status);
Run Code Online (Sandbox Code Playgroud)
然后有一个类似的服务方法:
@Transactional
public Job createJob(Job job) {
if (jobRepository.countByOwnerAndStatusIn(job.getOwner(), Job.PROGRESS_STATUS) == 0) {
// Sleeps just to ensure conflicts
Thread.sleep(1000);
Job newJob = jobRepository.save(job);
Thread.sleep(1000);
return newJob
}
else {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
但这样我没有得到预期的效果。
READ 和 WRITE 的 LockModeType 允许创建重复项。
PESSIMISTIC_READ 和 PESSIMISTIC_WRITE 的 LockModeType 可能会导致死锁错误。
所以我想我会选择以下两种选择之一:
INSERT...SELECT WHERE NOT EXISTS
进入 JPA/CrudRepository 方法?如果没有办法做到这一点,我想我会尝试访问底层jdbc连接并显式运行一个LOCK TABLE语句(或插入...选择,但我不喜欢这个想法,保留它JPA喜欢可能更好)。
希望我已经正确解释了自己。在此先感谢您的帮助。
| 归档时间: |
|
| 查看次数: |
1027 次 |
| 最近记录: |