c 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 sche
dule 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
SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();
c mysql 并发处理_mysql队列中实现并发读的实现方法解析相关推荐
- java抢单功能_基于消息队列的高并发抢单功能实现方法与流程
本发明涉及嵌入式软件中间件,具体涉及一种基于消息队列的高并发抢单功能实现方法. 背景技术: 中间件是一种独立的系统软件或服务程序,分布式应用系统借助这种软件在不同的技术之间共享资源,管理计算资源和网络 ...
- idea 断点线程_在IntelliJ IDEA中多线程并发代码的调试方法
通常来说,多线程的并发及条件断点的debug是很难完成的,或许本篇文章会给你提供一个友好的调试方法.让你在多线程开发过程中的调试更加的有的放矢. 我们将通过一个例子来学习.在这里,我编写了一个多线程程 ...
- mysql 统计条目_mysql 统计表中条目数量的几种方法
mysql 统计表中条目数量的几种方法 展开 通常的方法是: select count(*) from `table_name` select count(1) from `table_name` s ...
- mysql from_unixtime(_MySQL 数据库中日期与时间函数 FROM_UNIXTIME(), UNIX_TIME()
jinlinlucky:二.多路处理模块的配置说明|@||@|Apache HTTP服务器是一个强大的.灵活的能够在多种平台.不同环境下运行的Web服务器.由于不同的平台和不同的环境经常产生不同的需求 ...
- thinkphp mysql 预处理_thinkPHP框架中执行原生SQL语句的方法
本文实例讲述了thinkPHP框架中执行原生SQL语句的方法.分享给大家供大家参考,具体如下: 怎样在thinkphp里面执行原生的sql语句? $Model = new Model();//或者 $ ...
- java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)
相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...
- c++中文件的读处理多种方案解析
C++中读文件的方法 1. 读文件准备工作 2. 读取文件的3种方法举例说明 1.getline()全局函数 2. 流输入方式ifs<\ 1. 读文件准备工作 1.前提,首先读文件需要引入头文件 ...
- repeat mysql翻译_MySQL数据库中系统函数repeat有哪些功能呢?
摘要: 下文讲述MySQL数据库中系统函数repeat的功能说明,如下所示: 系统函数repeat的功能: repeat函数的功能: 重复前面字符串指定次数 repeat语法: repeat(str, ...
- C mysql添加_MYSQL将表 B C 插入表A方法
具体情形是:有三张表a.b.c,现在需要从表b和表c中分别查几个字段的值插入到表a中对应的字段.对于这种情况,我们可以使用如下的语句来实现: 1.INSERT INTO db1_name(field1 ...
最新文章
- 树莓派/PC实现实时摄像头数据共享(Python—picamera)
- [C#]统计文本文件txt中的行数(快速读取)
- 如何使用ember下拉框组件??
- ETSI GS MEC 014,UE 标识 API
- python处理流程-python的处理流程
- oracle导出库压缩参数,oracle数据库的定时备份:导出 压缩 归类
- Swif基础语法01
- NoNode for /hbase/hbaseid解决方案
- android 强制下线功能,Android学习之基础知识八—Android广播机制实践(实现强制下线功能)...
- Ubuntu中Go的环境搭建
- MCTS人工智能围棋
- it论坛 计算机科学概论,(毕业论文) 计算机科学与技术专业 IT技术论坛.doc
- selenium模块
- 如何用Python画出玫瑰曲线和蝴蝶曲线
- 免费的在线3D CAD【BimAnt】
- 函数编程之Function
- Java中HashMap底层实现原理
- QRJDC搭建实现QQ扫码登录对接青龙对接傻妞
- China-pub使我出离愤怒
- Acrobat Pro DC 教程:了解 Acrobat Pro DC 界面
热门文章
- VMware workstation 磁盘扩容
- Stanford机器学习---第十一讲.异常检测
- 【报告分享】2019年中国人工智能商业落地研究报告.pdf(附下载链接)
- (Object detection)目标检测从入门到精通——第五部分YOLO 算法
- 【问答集锦】联邦学习让隐私保护和海量数据学习兼得!
- HDU3544 不平等博弈
- windows删文件:找不到该项目,该项目不在xx中,请确认位置,然后重试 的解决方案
- Leetcode每日一题:118 + 119.pascals-triangle I and II(杨辉三角1和2)
- LeetCode每日一题:14.longest-common-prefix(最长公共前缀)
- 蓝桥杯 基础练习 报时助手