加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql应用mysql 队列 实现并发读

发布时间:2020-12-12 01:09:00 所属栏目:MySql教程 来源:网络整理
导读:《Mysql应用mysql 队列 实现并发读》要点: 本文介绍了Mysql应用mysql 队列 实现并发读,希望对您有用。如果有疑问,可以联系我们。 一个 MySQL 表可以看作是一个队列,每一行为一个元素.每次查询得到满足某个条件的最前面的一行,并将它从表中删除或者改变它

《Mysql应用mysql 队列 实现并发读》要点:
本文介绍了Mysql应用mysql 队列 实现并发读,希望对您有用。如果有疑问,可以联系我们。

一个 MySQL 表可以看作是一个队列,每一行为一个元素.每次查询得到满足某个条件的最前面的一行,并将它从表中删除或者改变它的状态,使得下次查询不会得到它.在没有并发访问的情况下,简单地用 SELECT 得到一行,再用UPDATE(或者DELETE)语句修改之,就可以实现.
代码如下:
SELECT * FROM targets WHERE status='C' LIMIT 1;
UPDATE targets SET status='D' WHERE id='id';

如果有并发访问,在SELECT和UPDATE语句之间可能会存在其他地SELECT查询,导致同一行被取出多次.为了保证在并发情况下仍然能正常工作,一种思路是使用数据库地锁来防止,就像在多线程环境下所做地一样.总之,要是的查询和修改为一个原子操作,不被其它的访问干扰.MySQL 5 支持存储过程,可以用它来实现.
单条 UPDATE 语句应该原子操作的,可以利用这个特性来保证并发访问情况下队列的正常工作.每次取元素时,先用 UPDATE 修改符合条件的第一行,然后再得到该行.可惜 UPDATE 语句没有返回值,重新用普通的SELECT的话又很难找到刚被改过的那条记录.
这里用到一个小技巧:在 UPDATE 时加上 id=LAST_INSERT_ID(id),再用 SELECT LAST_INSERT_ID() 即可得到刚修改的那条记录的id.还有一个问题,当表中不存在符合条件的记录,导致 UPDATE 失败时,LAST_INSERT_ID() 会保留原来地值不变,因而不能区分队列中是否还有元素.
ROW_COUNT() 返回上一个语句影响的行数,把它作为 SELECT 的一个条件,可以帮助解决这个问题.
最后,支持并发访问的完整解决方案为:

代码如下:
UPDATE targets SET status='D',id=LAST_INSERT_ID(id) WHERE status='C' LIMIT 1;
SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();

更新:在实现带优先级的队列时这种方法有问题,带有 ORDER BY ... 条件的 UPDATE 语句非常慢,例如:

代码如下: UPDATE targets SET status='D' WHERE status='C' ORDER BY schedule ASC LIMIT 1;


而单独查询和更新则是很快的:
代码如下:
SELECT id FROM targets WHERE status='C' ORDER BY schedule ASC LIMIT 1;
UPDATE targets SET status='D' WHERE id='id';


原来这是MySQL的Bug-12915,一年多以前提出来的,虽然关闭了,却只解决了部分问题,尚不支持WHERE,见MySQL 5.0.15 的 Changlog.无奈,上面这种巧妙的方法也没有实用价值了.
最后采用了一种折衷方案,如下:

代码如下:
UPDATE targets,(SELECT id FROM targets WHERE status='C' AND schedule<CURRENT_TIMESTAMP ORDER BY schedule ASC LIMIT 1) tmp SET status='D' WHERE targets.id=LAST_INSERT_ID(tmp.id);
SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读