msyql 除了加唯一索引,又其他办法防止同一时刻写入重复数据么?

2019-06-29 10:27:40 +08:00
 dyllen

情况是这样的,有些 api,第三方系统会推数据过来,有两个不同的 api,这两个 api 都会往一个表里面写同样的数据,两边业务逻辑上都有查重的,现在查历史记录,看见在有同时推数据到这两个接口的请求,导致写入重复的数据,创建时间都一样。除了加唯一索引有没有其他什么办法避免?

8778 次点击
所在节点    MySQL
43 条回复
jugelizi
2019-06-29 10:29:58 +08:00
队列 加锁
haiyang416
2019-06-29 10:32:49 +08:00
写操作串行化,扔队列呗。
srx1982
2019-06-29 10:33:35 +08:00
"两边业务逻辑上都有查重的",都查重了,还能重,那就是查重写得不对
LeeSeoung
2019-06-29 10:34:00 +08:00
先查后写。。mysql 好像没 merge into
laravel
2019-06-29 10:40:10 +08:00
为啥把 unique 除了?
R18
2019-06-29 10:41:36 +08:00
查重没有加锁…
qiyuey
2019-06-29 10:49:14 +08:00
你没有开事务吧
dyllen
2019-06-29 10:57:54 +08:00
@laravel 不知道,原来就没有加,现在加不了了,里面有不少重复的也不知道有没有用的数据
dyllen
2019-06-29 10:58:41 +08:00
@qiyuey 开了,两边是独立的。
dyllen
2019-06-29 10:59:53 +08:00
@R18 查到没有,我锁哪里,我锁表?
xuanbg
2019-06-29 11:03:06 +08:00
数据库唯一索引外,唯一解决办法,API 上面加分布式锁
Vegetable
2019-06-29 11:11:11 +08:00
队列
API 将数据塞到队列里,顺序消费掉避免并发写入.
这牺牲了实时性.如果要求实时返回插入结果的话不适用,只能使用事务
chrisliu1314
2019-06-29 11:15:18 +08:00
1 )加个字段,然后加唯一索引
2 )或者这两个 api 都调用底层的一个服务接口。服务接口里面采用分布式锁+先查后插
不知道是否可行
zisway
2019-06-29 11:28:20 +08:00
数据库解决,pg 是有语法可以插入时遇到重复直接忽略,但不知道 mysql 有没有,可以查文档看看。业务上解决可以用分布式锁,或者 api 不入库,而是扔到 redis 队列中,由 job 去取出入库。
799635347
2019-06-29 11:36:25 +08:00
1.分布式锁
2.mq
zy445566
2019-06-29 11:47:25 +08:00
如果没插入,开了事务还重复,九成是因为你没有判断每条 sql 是否有影响行数,就一个 try catch 就回滚了。事实上每条 sql 都要判断影响行数,如果影响行数为 0,理论上也是要进行回滚的。
zy445566
2019-06-29 11:48:23 +08:00
@zy445566 如果有插入,就开串行化级别的事务,但这个特别影响性能。
limuyan44
2019-06-29 12:00:18 +08:00
唯一索引建不了你怎么判断重复的,按你说如果重复的数据你都分不清哪一条有没有用,那你去重的意义在哪里?
harvies
2019-06-29 12:16:40 +08:00
15 楼正解
sunjiayao
2019-06-29 12:17:56 +08:00
看着是有历史遗留问题,导致存量数据有重复数据。而且不好清洗。如果对数据及时性要求不高,我觉得可以 copy 一张一模一样的表,并添加唯一索引。使用 duplicate key update 插入数据。然后定时 insert select 同步表数据。相对来说插入效率和开发难度比自己加锁要快吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/578494

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX