첫째, MySQL은 특히 매우 역동적 인 경우이를 구현할 수있는 최악의 소프트웨어 중 하나입니다. 그 이유는 MEMORY 및 MyISAM과 같은 엔진에는 전체 테이블 잠금 만 있고 InnoDB와 같은 더 적합한 엔진은 쓰기 페널티가 높고 (ACID 속성 제공) 공간적으로나 시간적으로 가까운 레코드에 액세스하는 데 최적화되어 있기 때문입니다 (메모리에 설정되어 있음). ). MySQL에 대한 좋은 변경 알림 시스템도 없습니다. 폴링으로 구현해야합니다. 있습니다 더 그 작업을 위해 최적화 된 소프트웨어의 조각 수십 .
그러나 성능 / 효율 요구 사항이 그리 높지 않은 경우 이러한 종류의 액세스를 성공적으로 구현하는 것을 보았습니다. 많은 사람들이 비즈니스 로직의 작은 부분만을 위해 완전한 별도의 기술을 도입하고 유지할 여유가 없습니다.
SELECT FOR UPDATE
찾고자하는 직렬화입니다. UPDATE / DELETE는 실행중인 MYSQL 트랜잭션 중에 항상 행을 잠그지 만 프로세스가 진행되는 동안 큰 트랜잭션을 피할 수 있습니다.
START TRANSACTION;
SELECT * FROM your_table WHERE state != 'PROCESSING'
ORDER BY date_added ASC LIMIT 1 FOR UPDATE;
if (rows_selected = 0) { //finished processing the queue, abort}
else {
UPDATE your_table WHERE id = $row.id SET state = 'PROCESSING'
COMMIT;
// row is processed here, outside of the transaction, and it can take as much time as we want
// once we finish:
DELETE FROM your_table WHERE id = $row.id and state = 'PROCESSING' LIMIT 1;
}
MySQL은 행을 선택할 때 하나를 제외한 모든 동시 선택을 잠 그게됩니다. 이로 인해 많은 연결이 동시에 잠길 수 있으므로 초기 트랜잭션을 가능한 한 작게 유지하고 한 번에 하나 이상의 행을 처리하십시오.