我们有一个系统具有基于数据库的队列,用于处理线程中的项目而不是实时。它目前的MyBatis实现调用MySQL中的这个存储过程:mysql存储过程从基于数据库的队列弹出
DROP PROCEDURE IF EXISTS pop_invoice_queue;
DELIMITER ;;
CREATE PROCEDURE pop_invoice_queue(IN compId int(11), IN limitRet int(11)) BEGIN
SELECT LAST_INSERT_ID(id) as value, InvoiceQueue.* FROM InvoiceQueue
WHERE companyid = compId
AND (lastPopDate is null OR lastPopDate < DATE_SUB(NOW(), INTERVAL 3 MINUTE)) LIMIT limitRet FOR UPDATE;
UPDATE InvoiceQueue SET lastPopDate=NOW() WHERE id=LAST_INSERT_ID();
END;;
DELIMITER ;
的问题是,这个弹出N项从队列但对于最后一项弹出队列只更新lastPopDate值。所以如果我们用limitRet = 5来调用这个存储过程,它会从队列中弹出五个项目并开始处理它们,但只有第五个项目会有lastPopDate集合,所以当下一个线程到来时,弹出队列就会获得项目1-4和项目6.
我们如何得到这个更新所有N条记录'弹出'数据库?
这是一个非常完整的答案感谢您花时间。我将要实现与此非常接近的事情并对其进行测试。我有点担心的一件事是,更新和select之间似乎存在小的竞争条件,因为记录没有被锁定为“FOR UPDATE”。这几乎肯定是一个比我们现在拥有的小得多的问题。这大部分都是我们使用的 – kasdega
。我们在UUID_SHORT()方面遇到了一些小问题(在mysql中不支持),所以我们使用了UUID()和varchar,而且我们遇到了排序问题,并通过在guid列上显式设置排序规则来比较我们解决的问题。除此之外,它已经实施并正在工作。谢谢。 – kasdega