高并发下数据库中如何解决重复插入数据的问题

昨天面试,被面试官问到。。。
比如用户注册时,先要验证用户名是否存在,但是在验证过后可能还会被插入相同用户名的数据,这就造成了冲突。
应该怎么解决?

6个回答

验证的同时,将用户名插入一个临时表,下一个用户验证时要与临时表数据一并比对,用户注册完成后删除临时表的当条记录

EvilSlyvanas
一只笨鸟丶 不太清楚你的表述,我觉得比对就会用到select,则就会出现同步的问题,除非你的临时表的用户名定义了唯一约束,用insert的成功和失败来判断,因为事务的级别问题,insert会锁表,所以可以用来判断。当然,这样的处理还不如在原来的表上设置唯一约束
2 年多之前 回复
tesily
菜鸟欧少 回复Mr_Manco: 不好意思,有段时间没上了。删除临时表的时间,必须是用户保存或取消保存。如果保存了,那么这个用户名已经在数据库中存在,又有新用户注册时,需要比较数据库的正式数据和临时数据。如果取消了,那么就不用考虑这个问题了,再有用户注册时,又重复之前的比较流程。
2 年多之前 回复
Mr_Manco
Mr_Manco 我是菜鸟小白 用户注册完成后删除临时表的当条数据 之后再注册有重复的用户名怎么办 这是临时表的数据已经没有了 怎么比较?
接近 3 年之前 回复

做事务处理,将判断、插入两个动作写在一个事务中

写在同一个事务其实也不能解决重复的问题 主要是设置唯一索引 相同用户名的时候 数据库自然会回滚后插入的

1、程序层面,设置单线程,线程内包含select重复校验和保存方法。这样第二个指令必须等到第一个指令执行完毕才执行。这样的好处是效果是绝对的,
但是极大并发下,效率低。
2、数据库层面。这就是乐观锁和悲观所了。
当验证用户的时候,如果数据库内有。直接返回。如果数据库内没有,则插入这条用户信息(也可以用临时表的方式),但是用户状态是无效,并将本条数据枷锁,而如果用本
用户进行注册的时候,其实是直接修改用户的状态变为有效。
所谓悲观所就是直接对这条信息for update,谁都不能用,就当前这个事物能用。
所谓乐观锁就是插入以后返回一个版本号。
接下来,如果有其他的用户也用这个用户名了。那版本号就加1,那就是看你俩谁快了。如果你点保存。的时候发现你的版本号小于数据库的版本号。
那你就要重新获取一个版本号,如果发现不小于,那这个用户名就是你的。如果发现已经生效了。那用户就是别人的了。

设置唯一索引(用户名)

EvilSlyvanas
一只笨鸟丶 回复菜鸟欧少: 保存的时候报错若你可以抓取对应的异常则可以知道是用户名有没有被占用了。
2 年多之前 回复
tesily
菜鸟欧少 唯一索引只能在保存的时候报错,不能反应此用户名没被占用
接近 3 年之前 回复

楼主,想知道这个验证用户名是否存在,然后还要去插入重复数据的业务场景是啥,为什么会有这样的需求呢?

qq_36271806
爱吃火锅的S 回复旋葎: 好的,明白了 谢谢
2 年多之前 回复
jkl012789
旋葎 老铁 你先验证了用户名不存在, 验证完成后在其他的用户那边刚好这时候也在验证这个用户名,也是不存在,他比你先注册完成,那这时候你再去点击注册,因为你已经校验不存在此用户名,所以你也会注册成功,这时候会出现重复的用户名。
接近 3 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐