Mysql 表字段修改 并发情况下避免重复

Mysql 表字段修改 并发情况下避免重复

一,场景

     多个用户同时修改用户名时,存在用户名相同的情况,而由于业务需要,用户名是不允许相同的,需要避免重复。

二,问题

     sql语句举例(伪代码):

	If(name not exited)		(1)
	{
		Update name;		(2)
	}

     一般都会先判断用户名是否存在,如果不存在,才会去更新数据库。但是这两个语句是分段的,如果有两个端的两个线程同时在进行这个操作,可能线程1,2同时执行完了(1)语句,此时判断重名条件已经走过了,两个线程同时执行update name,会导致存在相同的用户名。注意:将这两条sql语句合并成一条,执行时内部也是分段的,并不能解决问题。

三,解决方案

     对于单服务器而言,这个问题比较简单,我们不用考虑多端同时操作数据库。可以直接在服务器内存中创建缓存,存储每次更新后的用户名以及已有的用户名信息,当收到前端的请求进行用户名更新或者插入时,先到本地缓存中进行重名校验,再决定是否需要更新数据库。
     对于分布式服务器,就不能简单依赖服务器程序本地的同步和原子性操作了,我们需要从数据库本身入手,有以下两种方式:
(1)LOCK TABLE
     这种方式会锁全表,导致并发性能下降,此外,如果在 LOCK TABLE 和 UNLOCK TABLE 之间有异常,会导致锁无法释放,但是根据业务,如果不能加唯一约束,那也只能通过这种加锁方式来实现了,或者新建一个单独的锁表。

(2) 字段设置唯一约束
     将数据库表中的某个字段设置为unique,那么在对该字段进行增改操作时,数据库内存会帮我们保证该字段的唯一性,如果存在冲突会返回数据库执行错误。此方案在实际项目中有用到,实测TPS 500的场景。

发布了78 篇原创文章 · 获赞 79 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/bajianxiaofendui/article/details/104575350