2017-10-08 1 views
0

나는 동시 근로자 사이에 행을 배포하는이 쿼리를 사용 이 쿼리로 인해 교착 상태가 발생하는 이유는 무엇입니까?

SET @update_id := 0; 
UPDATE tablename 
    SET processed = -1, id = (SELECT @update_id := id) 
    WHERE processed = 0 
    LIMIT 1 
SELECT @update_id as id; 

는 때때로 교착 상태 예외를 던지고 난 그냥 다시 시작했습니다. 그러나 충분한 작업자 수가 많으면 매회 교착 상태가되어 재시도 루프에 걸릴 수 있습니다. 올바르게 다시 쓰는 방법?

답변

0

당신은 인덱스 processed 열이이 쿼리

SET @update_id := (SELECT id FROM tablename t WHERE processed = 0 LIMIT 1); 
SET @updated_id := 0; 
UPDATE tablename 
    SET processed = -1, id = (SELECT @updated_id := id) 
WHERE 
     id = @update_id 
     AND processed = 0; 

SELECT @updated_id as id; 

당신은 아무도에게 제로 updated_id를 얻을 때까지 여러 번에 실행해야 할 수도 있습니다를 시도해야합니다. 처리되지 않은 레코드가 없을 때 상황을 처리해야합니다.

대체 방법 : 각 프로세스 가정

는 고유 @process_Id을 가지고 있으며, 한 번에 하나 개의 레코드를 처리하고, 삭제 처리 후 -1 처리 세트.

UPDATE tablename SET processed = @process_id WHERE processed = 0 LIMIT 1;  
SELECT id FROM tablename t WHERE processed = @process_id; 
+0

정상적으로 작동해야합니까? select 하위 쿼리가 반환 된 후 업데이트가 발생하기 전에 행이 수정되면 어떻게됩니까? 0 행이 수정되면 반환 값을 확인하고 쿼리를 다시 시작해야합니까? – Poma

+0

'AND processed = 0'은 그것을 방지해야합니다. 예, 0 행이 수정되거나 0이 반환되면 검색어를 다시 시작해야합니다. 'processed = 0'이있는 행이 있는지 확인해야하므로 무한 루프가 발생하지 않습니다. 대체 접근법은 -1 대신에 ProcessId를 설정하는 것이고, 어떤 경우에는 추락 된 프로세스를 다뤄야 만합니다. '업데이트 된 tn 세트 처리 = 처리 된 값 = 0 한계 1; tn에서 처리 된 ID를 선택하십시오. = ' –

+0

' 일반 오류 : 1093 FROM 절의 업데이트에'tablename '대상 테이블을 지정할 수 없습니다. – Poma

관련 문제