2012-08-31 2 views
3

MySQL을 사용하여 큐를 만들려고합니다. 설정 한 방법은 업데이트가 큐 항목에 수신기 ID를 설정하기 위해 수행 된 후 업데이트가 수행 된 후 수신기 ID로 업데이트 된 항목을 선택하는 것입니다.select 쿼리에서 mysqli :: query()가 true를 반환합니다.

내가 직면 한 문제는 업데이트를 쿼리 한 다음 select를 수행하면 select 쿼리가 결과 집합 대신 true를 반환한다는 것입니다. 이것은 빠른 금액의 요청이있을 때 발생하는 것 같습니다.

왜 이런 일이 일어나는 지 아는 사람이 있습니까?

미리 감사드립니다.

스키마 :

CREATE TABLE `Queue` (
    `id` char(11) NOT NULL DEFAULT '', 
    `status` varchar(20) NOT NULL DEFAULT '', 
    `createdAt` datetime DEFAULT NULL, 
    `receiverId` char(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

큐에서 :

update `'.self::getTableName().'` 
set 
    `status` = 'queued', 
    `receiverId` = '%s' 
where 
    `status` = 'queued' 
    and `receiverId` is null 
order by id 
limit 1; 

select 
    * 
from 
    `'.self::getTableName().'` 
where 
    `receiverId` = \'%s\' 
order by id 
desc limit 1 
+1

게시자가 시도한 스키마, 코드를 게시하십시오. – Kermit

답변

1

이 어떤 종류의 경쟁 조건처럼 들린다. 당신은 MyISAM을 사용하고 있기 때문에 업데이트가 지연 될 수 있습니다 (특히 해당 테이블에 트래픽이 많은 경우).

true 반환은 select 쿼리가 제대로 완료되었지만 반환 된 빈 결과 집합 (행 없음)을 나타냅니다. 만약 당신의 논리가 50 밀리 초를 기다려 다시 시도한다면, 당신은 그 것이 올바르게 작동한다는 것을 알 수 있습니다.

편집 : 마지막 SELECT를 완료 할 때까지 UPDATE를하기 전에 테이블을 잠글 수 있습니다. 그러나 그것은 앱의 다른 부분의 성능을 떨어 뜨릴 수 있습니다. 가장 좋은 방법은 경쟁 조건에도 불구하고 앱을 강력하게 만드는 것입니다.

+0

그게 내가 생각한 것입니다. MySQL 서버 측에서 업데이트가 발생할 때까지 선택을 방지 할 수있는 방법이 있습니까? – Kyle

+0

동일한 프로세스 하위에서 대기열/큐를 모두 종료 한 다음 작업 부하를 하위 프로세스로 분산 시켰습니다. 나는 당신이 경주 문제에 대해 옳다고 생각합니다. 테이블에 대한 액세스를 요청하는 여러 스레드가 있었으며 MySql은 SELECT에 우선 순위를 부여하고 업데이트 우선 순위는 낮습니다. 따라서 select가 실행되면 업데이트가 보류 중입니다. 감사! – Kyle

관련 문제