MySQL 테이블을 동시에 읽고 쓸 수 있는 작업자가 여러 명 있다고 가정해 보겠습니다(예: jobs
). 각 작업자의 임무는 다음과 같습니다.
已排队
채용정보 찾기 RUNNING
작업자가 1단계를 실행할 때 적격한 작업(예: )이 없을 QUEUED
수도 있다는 점에 유의하세요.
지금까지 다음과 같은 의사 코드가 있습니다. 1단계에서 작업이 반환되지 않으면 거래를 취소(ROLLBACK
)해야 한다고 생각합니다. 아래 코드에서 이 작업을 어떻게 수행합니까?
BEGIN TRANSACTION; # Update the status of jobs fetched by this query: SELECT id from jobs WHERE status = "QUEUED" ORDER BY created_at ASC LIMIT 1; # Do the actual update, otherwise abort (i.e. ROLLBACK?) UPDATE jobs SET status="RUNNING" # HERE: Not sure how to make this conditional on the previous ID # WHERE id = <ID from the previous SELECT> COMMIT;
P粉5369091862023-12-22 09:14:00
당신이 원하는 것이 무엇인지 아직 명확하지 않습니다. 하지만 귀하의 작업이 다음 QUEUED
作业。将其状态设置为RUNNING
을 찾아 해당 ID를 선택한다고 가정해 보겠습니다.
단일 스레드 환경에서는 코드만 사용하면 됩니다. 선택한 ID를 애플리케이션 코드의 변수로 추출하여 WHERE 절의 UPDATE 쿼리에 전달합니다. write 문이 하나만 있으므로 트랜잭션도 필요하지 않습니다. SQLscript에서 이를 모방할 수 있습니다.
현재 상태는 다음과 같습니다.
으아아아대기 중인 다음 작업(id=2)을 시작하려고 합니다.
으아아아당신은 얻을 것이다
으아아아마지막 선택부터 시작합니다. 테이블의 상태는 다음과 같습니다:
으아아아작업을 시작하는 프로세스가 여러 개 있는 경우 이를 방지하려면 FOR UPDATE
锁定该行。但可以使用LAST_INSERT_ID()
를 사용해야 합니다.
위 상태부터 시작하여 작업 2가 이미 실행 중입니다.
으아아아얻을 수 있는 것:
으아아아새로운 상태:
으아아아UPDATE 문이 어떤 행에도 영향을 미치지 않은 경우(대기 중인 행 없음), ROW_COUNT()
将为 0
.
내가 인식하지 못하는 위험이 있을 수 있지만 실제로는 그렇게 접근하지도 않습니다. 차라리 jobs
테이블에 더 많은 정보를 저장하고 싶습니다. 간단한 예:
그리고
으아아아이제 실행 중인 작업은 특정 프로세스에 속하므로
를 사용하여 간단히 선택할 수 있습니다. 으아아아더 알고 싶을 수도 있습니다. queued_at
、started_at
、finished_at
.
P粉6355097192023-12-22 00:24:50
이번 주에 저는 귀하의 사례와 매우 유사한 것을 구현할 예정입니다. 여러 작업자가 각각 작업할 행 집합에서 "다음 행"을 가져옵니다.
의사 코드는 다음과 같습니다:
으아아아경합 조건(예: 여러 작업자가 동일한 행을 가져오려는 경우)을 피하려면 FOR UPDATE
을 사용하는 것이 중요합니다.
에 대한 자세한 내용은 https://dev.mysql.com/doc/refman/8.0/en/select-into.htmlSELECT ... INTO
을 참조하세요.