高并发情况下,防止用户名重复插入的问题,SpringMVC MySQL
有一个用户表,字段分别是, id, username, password ,分别记录用户的ID(主键),用户名,和密码。
我的业务逻辑中,要求用户名字段,绝对不能有重复。 否则整个系统就完全乱套了。
我之前的办法是,控制层中,在插入新用户之前,先判断一下这个用户名,是否已经存在?如果已经存在,就报错提示给用户,如果不存在,则执行插入操作。
伪代码如下:
事务开始
if(xxxDao.isUsernameExist("love")){
return "你输入的用户名已被占用,请尝试其他用户名,谢谢!";
/** 使用的SQL语句为:
select * from user where username = 'love'
*/
}else{
xxxDao.insertUser(user);
return "用户注册成功,请返回登录页面登录!";
/** 使用的SQL语句为:
INSERT INTO user(id,username,password) VALUES('xxxx','love','xxxxxxx')
*/
}
事务结束
一开始我自己测试,这段程序运行的灰常完美,什么问题也没有!
但是后来,问题,无情的来了。。。
当有多个人,比如100个人,并发访问的时候,就出现问题了:
这100个同志,同时注册 "love" 这个用户名,那么他们首先执行 if(xxxDao.isUsernameExist("love")) 这条语句,来判断user表里,是不是存在 love 这个用户名,那么他们同时得到的结果,是不存在,可以注册这个用户名,然后紧接着开始执行 INSERT INTO...操作了。 后果就是我的user表里,出现了100个用户名是 love的记录。。。。
这一下就完蛋了。。
那么我想请教一下各位大神,如果我把以上代码稍微做下修改,修改成下面这样:
事务开始
if(xxxDao.isUsernameExist("love")){
return "你输入的用户名已被占用,请尝试其他用户名,谢谢!";
/** 使用的SQL语句为:
select * from user where username = 'love'
*/
}else{
xxxDao.insertUser(user);
return "用户注册成功,请返回登录页面登录!";
/** 使用的SQL语句为:
INSERT INTO user(id,username,password) SELECT 'xxxx','love','xxxxxxx' FROM DUAL WHERE NOT EXISTS ( SELECT * FROM user WHERE username = 'love' )
*/
}
事务结束
这样的话,还会不会存在以上那个并发问题?求大神指点我,尽量的能不用锁就不去用锁,能不去修改事务隔离级别,就尽量不修改,除非实在没办法了