2011-11-04 6 views
0

동일한 mysql 테이블에서 행을 동시에 선택하는 프로세스가 5 개 이상 있습니다. 각 프로세스는 100 개의 행을 선택하고 처리하고 선택한 행을 삭제합니다.
원자 적으로 Mysql에서 행을 선택하는 방법?

하지만 동일한 행이 선택되고 2 회 이상 처리됩니다.

MYSQL 또는 Ruby on Rails 측에서 어떻게 일어나지 않도록 할 수 있습니까? 이 앱은 루비 레일에 내장되어

...

답변

4

행의 (귀하의 경우 "청구 됨"). 다른 프로세스는 미 청구 행을 선택해야하며, 이로 인해 프로세스가 서로의 행을 스테핑하지 못하게됩니다.

당신은 당신이 무엇을 노력하고 있습니다 알고, 어쩌면 시간 등,이 완료 여부

작동하는 데 시간이 너무 오래이며, 그래서, 당신은 프로세스 식별자를 사용하여 한 단계 더 걸릴하려면

그리고 예, 이전 질문으로 돌아가서 몇 가지 대답을 승인하십시오. 나는 적어도 하나는 당신이 확실히 놓친 것을 보았다.

3

당신은 당신의 테이블에 몇 가지 추가 열이 ... 에릭의 대답은 좋다,하지만 난 조금 정교하게해야한다고 생각 말 :

lockhost VARCHAR(60), 
lockpid INT, 
locktime INT, -- Or your favourite timestamp. 

이 NULL로 모든 기본. 그런 다음

당신은 수행하여 작업자 프로세스 "주장"행을 가지고 다음

UPDATE tbl SET lockhost='myhostname', lockpid=12345, 
locktime=UNIX_TIMESTAMP() WHERE lockhost IS NULL ORDER BY id 
LIMIT 100 

당신이 SELECT와 주장 행을 처리 ... WHERE lockhost = '호스트 _'와 lockpid = 12345

행 처리를 마친 후에는 필요한 모든 업데이트를 만들고 lockhost, lockpid 및 locktime을 NULL로 다시 설정합니다 (또는 삭제하십시오).

이렇게하면 둘 이상의 프로세스에서 한 번에 처리되는 동일한 행이 중지됩니다. 처리 할 호스트가 여러 개있을 수 있으므로 호스트 이름이 필요합니다.

배치를 처리하는 동안 프로세스가 충돌하는 경우 "잠금 시간"열이 매우 오래되었습니다 (처리 시간이 오래 걸릴 수 있습니다. 예를 들어 몇 시간 정도 걸릴 수 있음). 그런 다음 lockhost가 null이 아니더라도 오래된 "잠금 시간"이있는 행을 다시 확보 할 수 있습니다.

이것은 데이터베이스에서 꽤 일반적인 "대기열 패턴"입니다. 그것은 매우 효율적이지 않습니다. 대기열에 들어가거나 나가는 항목의 속도가 매우 높은 경우에는 적절한 대기열 서버를 대신 사용해보십시오.

관련 문제