쿼리 조건이 JPA 및 스프링을 충족하는 경우 행 삽입
Spring data JPA(Hibernate under the hood)에 의한 Database의 비관적인 locks와 비슷하다고 생각합니다만, 꼭 같은 것은 아니기 때문에 별도로 묻고 싶다고 생각했습니다.
mariadb 데이터베이스 위에 멀티 스레드/노드 스프링 부트 애플리케이션이 있으며 다음과 같은 테이블이 있습니다.
CREATE TABLE job (
id INT PRIMARY KEY AUTO_INCREMENT,
owner VARCHAR(50),
status VARCHAR(10) );
한 잔 하다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;
JPA/CrudRepository에서 이 작업을 수행하는 방법
나는 DB 업무로 나누었다.저장소 메서드를 정의했습니다.
@Lock(LockModeType.READ)
long countByOwnerAndStatusIn(String owner, List<String> status);
그리고 다음과 같은 서비스 방법을 사용했습니다.
@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;
}
}
하지만 이것으로 나는 원하는 효과를 얻지 못한다.
READ 및 WRITE의 LockModeType을 사용하면 중복을 생성할 수 있습니다.
PEASMISTIC_READ 및 PEASMISTIC_WRITE의 LockModeType을 사용하면 교착 오류가 발생할 수 있습니다.
다음 두 가지 방법 중 하나를 찾아야 할 것 같습니다.
- 이 모든 것을 얻을 수 있는 방법은 없을까?
INSERT...SELECT WHERE NOT EXISTS
JPA/CrudRepository 메서드로 변경하시겠습니까? - 카운트 체크와 인서트를 같은 잠금으로 효과적으로 랩할 수 있는 방법이 있습니까?
둘 다 할 방법이 없는 경우 기본 jdbc 접속에 접속하여 다음 명령을 실행합니다.LOCK TABLE
스테이트먼트(또는 삽입...)선택하지만, JPA를 그대로 두는 것이 좋다고는 생각하지 않습니다).
내가 제대로 설명했길 바란다.잘 부탁드립니다.
언급URL : https://stackoverflow.com/questions/54246960/insert-row-if-query-condition-met-jpa-and-spring
'programing' 카테고리의 다른 글
Java에서 목록을 "인스턴스화"하고 있습니까? (0) | 2023.01.20 |
---|---|
MariaDB 문자 인코딩 (0) | 2023.01.20 |
Pthread 라이브러리에서 스레드 제거 (0) | 2023.01.20 |
WordPress 설치의 wp_options 테이블에서 과도 상태를 제거할 수 있습니까? (0) | 2023.01.20 |
MySQL 날짜 문자열을 Unix 타임스탬프로 변환 (0) | 2023.01.20 |