사용자가 동시에 데이터를 삽입하는 테이블 COMMANDS
이 있습니다.InnoDB 테이블 쓰기가 가능하지만 읽기 허용
모든 삽입 후에 나는 (시간이 많이 소요되는) 계산을하고 결과를 다른 테이블 RESULTS
에 저장해야합니다.
동시에 모든 사용자는 COMMANDS
에서 데이터를 읽습니다.
내 질문은 :
이새로운 $command
삽입 한 후, 내 계산에 해당 테이블의 모든 행을 사용합니다. 모든 행은 계산에 영향을 미치며 현재의 계산이 이루어지고 결과가 저장 될 때까지 새로운 삽입을 위해이 테이블을 잠그기 때문에 이전 $commands
에 영향을 미칠 수 있습니다. 또한 다른 사용자가 현재 상태 인 COMMANDS
을 볼 수 없도록 차단하고 싶지 않습니다.
잠깐 읽고 잠그지 않고 쓰기 위해 테이블을 잠급니다.
저는 InnoDB 엔진을 사용하고 있습니다. 잠금에 관한 몇 가지 문서를 읽었지만 완전히 혼란 스럽습니다. 그것은 바보 같다하지만 현재 내가 더 나은 및 영리 솔루션이 있어야 알고
public function storeNewCommand($command){
// $busy_flag is an app level global that can be read by all user sessions
if($busy_flag){
usleep(10000);
return $this->storeNewCommand($command);
}
$busy_flag = true; //(lock)
/*
...insert new $command to COMMANDS
...do calculations using all comands including last one
...store results in RESULTS
*/
$busy_flag = false; //(unlock)
}
아래 같은 메커니즘을 사용하고
공유하고 배타적 인 잠금, 의도 잠금 장치, 갭 잠금 ... 이것은 루프가없고 잔다. 그러나 나는 어느 것을 사용해야하는지 모른다.
"사용자 입력 프로세스"를 "DB 프로세스로 저장"에서 분리하고 계산하는 동안 새 행 삽입을 피하는 방법을 제어 할 수 있도록 대기열을 설정하는 방법을 찾아보십시오. – Alfabravo
감사합니다 @ Alfabravo 일부 대기열 작업을 사용하고 있지만 그들은 비동기 작업을하고 모든 삽입 후 모든 저장된 명령의 현재 상태를 매우 중요합니다. 따라서 전치 연산이있는 경우 데이터베이스 수준에서 삽입을 차단하고 싶습니다. – Jaxovee
저에게는 테이블 레벨 잠금을 에뮬레이트하는 것은 잘못된 전략입니다. 사용자가 어떻게 사용되는지에 상관없이 모두 동일한 대기열과 동일한 DAO를 통해 요청을 보내야합니다. – Alfabravo