mysql C api 多线程多连接 存储过程 锁表问题
2016-05-28 00:32
519 查看
问题环境:
1,centos yum 安装的mysql 5.5
2, 多线程(监听到一个请求新建一个处理线程), 多连接(每个处理线程单独打开一个连接), 使用存储过程更新流水号(mysql设置 mysql_autocommit(m_pDB, 0);)
3,因为连接已经关闭自动提交功能,所以在存储过程中并没有使用commit命令。commit 命令在c函数中执行,和其他SQL语句一起提交的一次。
问题现象:
当多个请求同时到达时,只有第一个可以正常更新获取流水号,其他请求处于等待状态。但现象是必须等待到第一个DB连接释放时其他请求才可以有一个正常访问。这就有问题了。
引起结果:mysql_query 执行commit命令 没有提交存储过程中的update语句。why?
1,在c api 环境下不要关闭自动提交功能,应保持默认为开。只有在使用到的时候使用SQL语句进行设置,
2,在C api 环境下,
并不能提交存储过程中的语句。
3, eg:
说明:程序更新流水号,每次增加1。如果使用下边的存储过程,并没有能等到想到的结果。
做如下修改:
c api代码中删除:
存储过程中添加:
再次执行结果正常。
1,centos yum 安装的mysql 5.5
2, 多线程(监听到一个请求新建一个处理线程), 多连接(每个处理线程单独打开一个连接), 使用存储过程更新流水号(mysql设置 mysql_autocommit(m_pDB, 0);)
3,因为连接已经关闭自动提交功能,所以在存储过程中并没有使用commit命令。commit 命令在c函数中执行,和其他SQL语句一起提交的一次。
问题现象:
当多个请求同时到达时,只有第一个可以正常更新获取流水号,其他请求处于等待状态。但现象是必须等待到第一个DB连接释放时其他请求才可以有一个正常访问。这就有问题了。
引起结果:mysql_query 执行commit命令 没有提交存储过程中的update语句。why?
知道原因的话留言解惑。我署名会更新,谢谢!
关于mysql C API事务功能两点使用体会记录文档。1,在c api 环境下不要关闭自动提交功能,应保持默认为开。只有在使用到的时候使用SQL语句进行设置,
mysql_autocommit(m_pDBAccess, 0);//关闭自动提交
2,在C api 环境下,
mysql_query(m_pDBAccess,"commit"); // 或 mysql_commit(m_pDBAccess);
并不能提交存储过程中的语句。
3, eg:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <mysql/mysql.h> int main(int rgvs, char **rgva) { MYSQL *m_pDBAccess; m_pDBAccess =mysql_init(NULL); if(!m_pDBAccess){ printf("get mysql init is NULL\n"); return -1; } if(!mysql_real_connect(m_pDBAccess, "192.168.1.203", "root", "123456", "tposdb", 0, NULL, CLIENT_MULTI_STATEMENTS)){ printf("get mysql_real_connect is NULL\n"); return -1; } mysql_autocommit(m_pDBAccess, 0); char value = 1; mysql_options(m_pDBAccess, MYSQL_OPT_RECONNECT, (char*)&value); if (mysql_query(m_pDBAccess, "CALL GetBankSerialNo('35220001', '310111173110010');")) // 如果失败 { mysql_rollback(m_pDBAccess); printf("aa\n"); return -1; } // mysql_rollback(m_pDBAccess); printf("bb\n"); mysql_query(m_pDBAccess,"commit"); // mysql_commit(m_pDBAccess); mysql_close(m_pDBAccess); m_pDBAccess = NULL ; mysql_thread_end(); return 0; }
说明:程序更新流水号,每次增加1。如果使用下边的存储过程,并没有能等到想到的结果。
DELIMITER $$ /*!50003 CREATE DEFINER=`root`@`%` PROCEDURE `GetBankSerialNo`( pTID varchar(8), pMID varchar(15) ) BEGIN select SerialNo, BatchNo from tab_platmerterm where MID=pMID and TID=pTID; UPDATE tab_platmerterm SET SerialNo=SerialNo+1 where MID=pMID and TID=pTID; -- 使用c api 时,在存储过程外执行commit 则不起作用。 -- 而且,如果在多线程多连接情况,autocommit设置为关闭,当再次执行update 时,并且之前已经有连接打开没有关闭情况,当前操作要一直等待上次连接断开才能正常执行。 -- 因为上次连接没有关开,并且存储过程中的sql语句没有提交,还在锁状态 END */$$ DELIMITER ;
做如下修改:
c api代码中删除:
mysql_autocommit(m_pDBAccess, 0);
存储过程中添加:
set session@@autocommit=0; -- ……sql语句 commit;
再次执行结果正常。
相关文章推荐
- MYSQL常用命令
- mysql下的加密解密函数
- mysql 批量更新多条记录(且不同值)的实现方法
- 新安装的mysql必须调整的10项配置
- mysql C api 多线程多连接 客户端实现
- MySQL内存及虚拟内存优化设置参数
- MySQL安全策略(MySQL安全注意事项)
- MYSQL分页limit速度太慢的优化方法
- mysql主键的缺少导致备库hang住
- mysql同步问题之Slave延迟很大优化方法
- MYSQL常用命令
- Mysql 密码忘记了,呃呃呃
- mysql 笔记分享
- mysql 笔记分享
- Win7-64位mysql的安装和配置
- MySql procedure
- MySQL数据库备份:完全备份+增量备份
- 简单的MYSQLI事务处理
- MYSQLI预编译
- 终端进入MySQL