0

0

MySQL问题解决:Commands out of sync; you can't run this command n

php中文网

php中文网

发布时间:2016-06-07 17:27:54

|

4261人浏览过

|

来源于php中文网

原创

在某个场景下,我们在向table1中insert一条记录后,需要得到得到它的ID,然后update与之匹配的另一张表table2中的记录。由于inser

录制程序有一功能:将录制的文件信息写入mysql数据库,供bs系统查询。
 
因此封装了一个mysql类,进行数据库操作。
 
主要接口为update():执行sql语句。
 
现在问题来了:
(一)在某个场景下,我们在向table1中insert一条记录后,需要得到得到它的id,然后update与之匹配的另一张表table2中的记录。由于insert本身并不返回结果集,因此我们无法直接得到插入记录的id。
 
那该怎么办呢?
之前从bs组得到的方法是:在table1中执行insert后,立即执行另一条语句:“select @@identity;”;该语句会返回最后插入的那条记录的id,这样问题就解决了。
 
但是,在一次codeview上,头儿提出了一个问题:如果在多线程中,在向table1执行insert后,另一个线程也执行了sql语句对数据库进行操作,这时再执行“select @@identity;”,能得到正确的结果吗?
很显然,确实存在这种问题:即我们无法保证整个过程的原子性,但这可以通过加锁来解决。
头儿又问:那这时候如果其他的客户端连接到数据库,执行了查询,会更改“select @@identity;”的结果吗?
当时没考虑到这一点,后来通过查询mysql手册(),发现系统变量identity的作用范围是“session”,也就是其他客户端、其他连接执行的query不会更改本次连接的identity变量的值,因此不会有影响。
 
后来发现mysql提供了内部函数last_insert_id(),我认为比“select @@identity;”更合理。
 
(二)另一个问题,,针对有些查询,我们需要获取并处理结果集。
原来是在mysql类中封装了一个成员变量mysql_res* m_res,用来保存有返回的查询结果集。这样一来,我们执行update()的后,如果需要获取结果集就调用getqueryresult()来获取结果集,用完之后再释放掉。
但是问题在于:在多线程环境中,我们可能有多个update()需要获取结果集,但是如果它们共用一个成员变量m_res来存储结果集的话,我们必须等待一次查询使用完它的结果集并释放后才能执行下一次的update(),否则mysql就会报错:“”,因为此时m_res还未被释放,不能执行下一次查询。
 
针对以上问题,我们的解决办法是:对查询接口做调整。
一共提供两个查询接口:
(1)update():执行查询;针对问题(一),开启multi-query支持,允许一次执行多条sql语句,具体操作参看();这样我们在upadte时使用类似

?

insert into  t_alarm_record_file  (recordPath,recordName,hostIp,startTime,endTime,deviceId,programNumber,deviceType,interfaceNo,alarmType,alarmTime) values ('/figure/data/AlarmRecord/StreamTS/1-码流_魅力音 乐主路/2011-11-07/20111107150116.ts','','10.0.60.2','2011-11-07 15:01:16','1970-01-01 08:00:00',37486602,3905,'0',1,12,'2011-11-07 15:01:20');update  t_alarm  set fileId = LAST_INSERT_ID()  where deviceId = 37486602 and programNumber = 3905 and alarmType = 12 and alarmDate = '2011-11-07 15:01:20' and fileId is null


 的语句一次执行两条sql语句就可完美的解决这种问题了;
(2)Update2():执行查询,并返回结果集给调用者,由调用者自己处理并决定何时释放该结果集,由于该结果集是以参数的形式返回的,因此多线程不会受到影响。
 
但在实际测试中,还是出现问题:"Commands out of sync; you can't run this command now",我们的日志显示:?

2011-11-07 15:01:28,660: INFO  : Update OK!sql: insert into  t_alarm_record_file  (recordPath,recordName,hostIp,startTime,endTime,deviceId,programNumber,deviceType,interfaceNo,alarmType,alarmTime) values ('/figure/data/AlarmRecord/StreamTS/1-码流_魅力音 乐主路/2011-11-07/20111107150116.ts','','10.0.60.2','2011-11-07 15:01:16','1970-01-01 08:00:00',37486602,3905,'0',1,12,'2011-11-07 15:01:20');update  t_alarm  set fileId = LAST_INSERT_ID()  where deviceId = 37486602 and programNumber = 3905 and alarmType = 12 and alarmDate = '2011-11-07 15:01:20' and fileId is null

Clickable
Clickable

用AI在几秒钟内生成广告

下载

2011-11-07 15:01:35,331: ERROR  : Update failed!sql: insert into  t_alarm_record_file  (recordPath,recordName,hostIp,startTime,endTime,deviceId,programNumber,deviceType,interfaceNo,alarmType,alarmTime) values ('/figure/data/AlarmRecord/StreamTS/1-码流_魅力音 乐主路/2011-11-07/20111107150116.ts','','10.0.60.2','2011-11-07 15:01:16','1970-01-01 08:00:00',37486602,3905,'0',1,13,'2011-11-07 15:01:27');update  t_alarm  set fileId = LAST_INSERT_ID()  where deviceId = 37486602 and programNumber = 3905 and alarmType = 13 and alarmDate = '2011-11-07 15:01:27' and fileId is null, ERROR:Commands out of sync; you can't run this command now


在第一次调用Update()执行多条sql语句时成功,但以后的所有调用都失败了。
 
经过查找,发现问题在于:在Update()中执行多条sql语句时,

如果仅仅是插入等不需要返回值的SQL语句,也一样得读完整个resault集并释放,最小化的写法:
 
do
{
    result = mysql_store_result( mysql );
    mysql_free_result(result);
}while( !mysql_next_result( mysql ) );
 
经过这么一处理,问题终于解决了。

linux

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

150

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

88

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

90

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

61

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

493

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

16

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

12

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

5

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号