求MySQL单库在高并发下通过读取数据判断是否写入数据的替代方案?

Sturn 发布于 2015/04/26 17:35
阅读 1K+
收藏 0

环境:mysql5单库(innodb),php5,nginx

现在的逻辑判断如下:

通过mysql进行查询,有数据不进行任何操作,无数据进行写入一条新数据

问题:当并发量大的时候,mysql会同时插入相同的数据3条左右,也就是说mysql做不了这样的逻辑处理。

我的解决办法:根据来访用户的session写入一个标记,如果有标记则不进行下面的数据库操作,但是还是不能挡住重复数据的出现。


请教大家有没有其他的办法解决我遇到的问题?(消息队列做这个可以吗?如果不用消息队列用Redis做标记(逻辑类似上面的session)的话是否可行?再高并发的情况下Redis是否也会出现类似MySQL的情况)




加载中
1
maradona
maradona

session不妥,这个只能解决同一个用户的重复提交,但两个用户在不同浏览器上提交了重复数据,因为校验的查询和实际数据插入都有一个比较长的时间差,那就会出现业务上数据重复的问题

如果该字段不能建唯一索引的话,一般只能考虑在一个公共访问的数据上控制唯一,内存数据库或者关系数据库都可以做到这点的,redis可以考虑cas锁,关系数据库可以做一个中间表,每次业务开始前就往该表插入一条数据(该表有一个唯一索引,如何设计你自己考虑),业务结束就删掉,考虑到意外情况还是设置一个过期时间,定时任务批量删除过期时间,基本保证不会数据重复


3
铂金胖子
铂金胖子

mysql不清楚,我用过oracle,db2都是用唯一索引来控制。

S
Sturn
谢谢此法 可行,不过我们还有一个调用接口在调用数据库之前
1
泡不烂的凉粉
泡不烂的凉粉
唯一索引,联合唯一索引绝对可以避免。写入会被阻止。是以错误还是异常的形式抛出完全根据配置决定。
S
Sturn
多谢你的回答
0
龙上
龙上
用事务加锁
S
Sturn
是个好办法多谢
0
梦想岛
梦想岛
用pdo 做事务
0
张无聊
张无聊
消息队列可以
0
南湖船老大
南湖船老大
使用序列嘛!MySQL不是有主键么,不写的话,它是自动生成的么,如果你指定了,那主键无法重复,也就无法重复插入了。
0
hylent
hylent

唯一索引约束 插入的时候 可以考虑使用replace into

我觉得你这种情况可以先把数据放到redis里面 然后再通过一个一直运行的脚本读取redis插入到mysql中

0
Brin想写程序
Brin想写程序

二次提交思路。。

首先,查询发现没有记录,而且标记位为0,然后更新标记位为0+1,表示准备插入了,然后再查询一遍标记位是否为1,若不为1,那么说明有冲突。若为1,那么正常插入。

插入后标记为更新为0.

 

解决冲突的策略:

1.重来一遍。。最省事

2.如果不愿意重来一遍,update标记位,将标记位减一,然后,再查一遍标记位,若还是大于1,那么放弃执行,若等于1,那么正常执行。。

0
月影又无痕
月影又无痕
用队列是可以的。
返回顶部
顶部