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

mysql并发插入

2016-05-19 19:54 232 查看
通常我们对表进行插入的时候,是这样操作的:
start transaction;
select * from t where id='x';
if not exist:
insert into t(id,c) values('x',1);
else:
update t set c=c+1 where id='x';
commit;


但这样会存在一个问题,如果两个id='x'的并发插入同时到达,那么select的时候都没有查到,insert时就会发生主键冲突。如何做到两个并发插入顺序操作并且下一个插入基于上一个插入的结果进行更新呢?因为mysql RR模式下,事务之间是相互隔离的,事务1如果已经插入成功并且提交,在事务2中,第一次没有select到数据,第二次select结果也是一样的(如果没有update)。另一个问题是,如果感知到别的事务已经插入了数据。研究了一下mysql,总结了一下:
start transaction;
select * from t where id='x'; // 获取数据
if exist:
update t set c=c+1 where id='x'; //如果存在可以直接更新
return;
rows=insert ignore into t(id,c) values('x',1); // insert ignore,如果不存在则返回1表示插入成功,如果已存在会返回0
if rows==1:
return; // 插入了当前不存在的行,可以返回
else rows==0: // 表示插入时数据库已经存在了id='x'的行
update set d='xxx' where id='x'; // 更新一个不太重新的列,例如时间,获取锁,因为update之后再select可以获取到最新的行并且锁住记录
select * from t where id='x'; // 此时获取到的就是最新的行,并且其他update都被锁住
nc=c; // 程序拿到的c就是当前最新的c
nc+=1; //在应用程序中重新计算
update t set c=nc where id='x'; // 最后更新回去
commit;


使用mysql 命令演示一下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: