2017-10-18 3 views
0

사용자가 동시에 데이터를 삽입하는 테이블 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) 

} 

아래 같은 메커니즘을 사용하고

공유하고 배타적 인 잠금, 의도 잠금 장치, 갭 잠금 ... 이것은 루프가없고 잔다. 그러나 나는 어느 것을 사용해야하는지 모른다.

+0

"사용자 입력 프로세스"를 "DB 프로세스로 저장"에서 분리하고 계산하는 동안 새 행 삽입을 피하는 방법을 제어 할 수 있도록 대기열을 설정하는 방법을 찾아보십시오. – Alfabravo

+0

감사합니다 @ Alfabravo 일부 대기열 작업을 사용하고 있지만 그들은 비동기 작업을하고 모든 삽입 후 모든 저장된 명령의 현재 상태를 매우 중요합니다. 따라서 전치 연산이있는 경우 데이터베이스 수준에서 삽입을 차단하고 싶습니다. – Jaxovee

+0

저에게는 테이블 레벨 잠금을 에뮬레이트하는 것은 잘못된 전략입니다. 사용자가 어떻게 사용되는지에 상관없이 모두 동일한 대기열과 동일한 DAO를 통해 요청을 보내야합니다. – Alfabravo

답변

1

(기본값은 50 초) 내에 긴 물건을 넣을 수 있다면 BEGIN ... COMMIT을 사용하십시오. (개인적으로는 50 초가 아니라 2 초 이상으로 제한 할 것입니다.)

그렇지 않으면 다른 모든 방법을 고안하십시오. 작가 인의 테이블에 모두 "중요합니다. 섹션". 아마도 단일 열이있는 1- 또는 2- 열 표 이상일 필요는 없습니다.

뮤텍스를 잡을 때는 fetch, set 등을 트랜잭션에 캡슐화하고 실패에 대응해야합니다. 자물쇠를 얻은 후, 느린 물건을 진행합니다. 마지막으로 잠금 장치를 해제하십시오.

경고 : 충돌 또는 소프트웨어 버그가있는 경우 잠금을 해제하는 코드가 실행되지 않을 수 있습니다. 따라서 타임 스탬프와 mutex가 "긴"시간에 해제되지 않았 음을 알리는 것이 좋습니다. 문제에 대한 이메일을 보내고 자물쇠를 지울 수 있습니다.