insert 重复插入问题

2019-01-31 12:49:44 +08:00
 wmhack

先写点伪代码:

select * from user where email = 1000@qq.com and sex = 1;

if ( rs = null ){ insert ………… }

这种写法在单机单线程的情况不会出问题,可生产是两台机器。

有一次刚好碰到了两台机器同是 select,结果为空,就同时插入了,

导致后来出现了两条记录。

问一下各位 V 友,这种情况要怎样解决呢?

3384 次点击
所在节点    问与答
36 条回复
nybux
2019-01-31 13:01:49 +08:00
1.select for update
2.用唯一
3.为啥邮箱和性别要唯一?
id4alex
2019-01-31 13:03:24 +08:00
上事务
milesnihao
2019-01-31 13:05:24 +08:00
数据库事务和锁?
GDC
2019-01-31 13:06:02 +08:00
加唯一键
itskingname
2019-01-31 13:06:43 +08:00
上分布式锁。
wmhack
2019-01-31 13:23:44 +08:00
@nybux 这里不是 update 操作啊
wmhack
2019-01-31 13:25:04 +08:00
@GDC 目前我们是做了唯一索引,还有方法加了 sychnazed,但这不是最优方案啊。
liprais
2019-01-31 13:25:14 +08:00
你的隔离级别设的是啥
wmhack
2019-01-31 13:26:56 +08:00
@nybux 这里只是举这么一个例子。实际情况,不是这两个条件。
wmhack
2019-01-31 13:28:48 +08:00
@liprais 感觉跟隔离级别没有太大关系,主要是两台机器同时 select 了一样的结果出来
RoyL
2019-01-31 13:29:47 +08:00
@wmhack
....for update 是锁,看来你一点不懂 sql
ixiaozhi
2019-01-31 13:30:42 +08:00
1. 加个 requestid 从前端到后端做锁
2. 几个唯一条件联合做锁,如 redis
wmhack
2019-01-31 13:33:06 +08:00
@id4alex 事物也控制不了同时 select 呀
id4alex
2019-01-31 13:41:45 +08:00
@wmhack

上事务 加上 insert tablename select 'col1' as col1, 'col2' as col2 from 伪表 where not exist select 1 from tablename where your condition
GoLand
2019-01-31 13:44:16 +08:00
这加个 unique key 就能解决的吧。
id4alex
2019-01-31 13:44:59 +08:00
前面也不用判断 RS == null 了, 直接执行这个 SQL 就可以了
gejun123456
2019-01-31 13:46:57 +08:00
加了唯一索引 就不会两条都插入了
haoz1w0w
2019-01-31 14:16:53 +08:00
唯一索引
ThirdFlame
2019-01-31 14:30:32 +08:00
唯一所以 可以避免两次插入,第一次插入成功了,第二次就出错了。 也就无需 select 了,直接干
wmhack
2019-01-31 14:51:13 +08:00
@ThirdFlame 是的,这是第二重限制。但报错的方式有时也不太好,如果没有更好的方案,那就只能靠唯一索引去控制了

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

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

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

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

© 2021 V2EX