Answers:
首先: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将在选择行时锁定除一个并发选择之外的所有并发选择。由于这可能同时导致大量锁定的连接,因此请使初始事务尽可能小,并尝试一次处理多于1行的数据。