如何处理对mysql的多线程请求以获得空闲行?

如何处理对mysql的多线程请求以获得空闲行?,mysql,multithreading,Mysql,Multithreading,假设您有一个由100000个作业组成的表,每个作业都需要处理 job_id (int) job_details (whatever) job_status (Enum: Not processed, Processing, Processed) 例如,我的核心软件有100个线程处理这些作业,因此每个线程都需要处理一个作业,它得到一个自由作业,因此它查询一个未处理的作业,将其标记为处理,完成后将其标记为已处理 问题是当100个线程开始工作时,因为当它们查询Select*from jobs whe

假设您有一个由100000个作业组成的表,每个作业都需要处理

job_id (int)
job_details (whatever)
job_status (Enum: Not processed, Processing, Processed)
例如,我的核心软件有100个线程处理这些作业,因此每个线程都需要处理一个作业,它得到一个自由作业,因此它查询一个未处理的作业,将其标记为处理,完成后将其标记为已处理

问题是当100个线程开始工作时,因为当它们查询
Select*from jobs where job\u status='Not processed'limit 1
update jobs set job\u status='processing'where job\u id=%job\u id%
时,许多线程一起开始工作!这是非常错误的


如何正确执行此操作?

如果
作业
是InnoDB表,则可以在事务中使用分配单个作业:

BEGIN
SELECT * FROM jobs WHERE job_status = 'Not processed' LIMIT 1 FOR UPDATE
UPDATE jobs SET job_status = 'Processing' WHERE job_id = ?
COMMIT
为更新指定
将锁定所选行。同时执行
SELECT
查询的单独事务(线程)将等待第一个事务完成

或者,如果修改
作业
表以记录已为哪个线程分配了任务,则可以在不执行事务的情况下执行分配。首先,分配一个作业,将作业的
owner\u thread
属性设置为执行线程唯一的标识符:

UPDATE jobs 
   SET job_status = 'Processing', owner_thread = ? 
 WHERE job_status = 'Not processed'
 LIMIT 1
然后使用执行线程的唯一标识符检索已分配作业的详细信息:

SELECT job_id, job_details FROM jobs WHERE owner_thread = ?

根据我的经验,MyIsam比InoDB快得多,有解决方案吗?Thanks@EBAG我概述的第二个解决方案(使用
owner\u thread
列)应该适用于MyISAM表。