您的位置:首页 > 数据库 > MySQL

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?

知道原因的话留言解惑。我署名会更新,谢谢!

关于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;


再次执行结果正常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: