首页 > 其他分享 >怎样才能保证注册用户名唯一

怎样才能保证注册用户名唯一

时间:2023-01-01 23:56:45浏览次数:39  
标签:userName 王二麻子 事务 用户名 删除 用户 问题 注册 怎样才能

  1. 首先这可能不是一个很简单的问题,很多程序员大概会这么写

    这样写有问题吗?明显,并发情况两个用户同时进入17行,都查询到 null,然后都执行22行,数据库插入了两条 同样的 userName。这写法不可用。

  2. 既然数据库会重复,那么我们就在数据库userName字段加上唯一索引,改成下面写法

现在有问题没?明显重复的问题解决了。但是问题来了,产品要求我们数据库可以删除用户,但是不能物理删除用户,删除用户以后userName依旧可以注册,或者说这个不是userName,而是唯一的用户游戏昵称。

  1. 然后张三想到假删除字段和userName建立唯一索引

    这时候可用吗?假删除以后,确实可以可以用这个userName重新注册,问题来了,这个新的userName还能再次删除吗?明显不能,唯一索引冲突。

  2. 这时候李四说我有办法,我假删除字段不用0和1 表示,我用0 表示没删除,删除时间的毫秒数表示已删除。这样就能重复删除了。

问题解决了吗?很大程度上解决了,毕竟注册的时候 userName 和 假删除字段0 只能存在一个,所以删除不可能同时删除2个,不会重复的删除时间,即便允许恢复删除,也只能吧对应userName并且状态是0 的先删除,然后再吧已经删除的改成 0,完美解决。

  1. 王二麻子这时候说话了,我们别的假删除都是0,1,你搞个球呀,风格另类而且一个bit能能表示的状态,你用了一个Long来存。我可以加个redis锁来解决这个问题,不用数据库的唯一索引,不搞风格不统一的假删除字段。

能解决问题吗?测试经过简单的测试,确实没问题,然后项目上线稳定允许3个月,突然有一天出现了2个userName重复的用户,大家使劲找,使劲查日志,检查代码终于发现上面37行锁释放以后事务还没有提交,但是另外一个事务已经可以获取这把锁了,另外一个事务读不到当前事务未提交的数据,然后也写了一条,userNam就重复了。

  1. 王二麻子说小问题,锁在事务提交之前我就释放,才出的问题,那么我就在事务提交之后在释放。

这下锁在事务执行以后释放了,完全没得问题,测试随便测测,确实没得问题上线稳定允许了1 年,确实没有在出现userName重复的问题。

  1. 一年后,因为项目稳定允许,给公司挣了很多钱,隔壁公司把他们整个团队都挖走了,包括王二麻子和产品经理。新来的产品经理决定在创建用户的时候初始化用户钱包。新来成程序员老李直接在插入用户下面加了一句初始化用户钱包,毕竟已经有@Transactional了,所以在一个事务环境,可以保持钱包和用户同时完成或者同时回滚。

    更新上线以后,初始化钱包的逻辑是有bug,结果钱包没有初始化,用户却创建成功了。大家找了半个月然后发现doRegister是内部调用,上面的事务注解根本没生效,只是因为之前没有多次更新所以没有出问题.

    1. 一查代码王二麻子写的,然后大家一起骂王二傻逼,并且做了修改。

然后问题终于解决了用户注册和钱包初始化,终于保持一致性,之前的隐藏坑也填上了,大家开始愉快的迭代,过上了混吃等死的日子。

  1. 为了提高注册用户数量,产品搞了一个活动,扫码注册送电瓶车,扫码以后拿到手机号作为userName,然后写入抽检结果,并且注册。老李吧程序改成下面这样。

上线以后,活动地点网络太差,大量网络重试,同一个手机号瞬间多次执行抽取电驴的方法,然后大家发现又出现了很多重复的userName。这个userName重复的问题怎么没完没了?隔壁公司被挖过去的张三歪嘴一笑,老子早就说了用userName+删除时间做唯一索引了,你们都被王二麻子坑了!

  1. 老李仔细的查找2天终于发现了,原来释放锁必须要在doRegister所在的事务提交以后,register这个方式之前是没有事务环境的,现在套了一个抽奖的方法,所以就出问题了。

  2. 问题找到了,但是怎么解决呢?注册的doRegister要求独立提交,register要求以非事务的方式执行,抽奖方法 要求 注册和抽奖 在一个事务里面执行,这他妈是矛盾的呀?只能吧加锁的力度提到抽奖的外层,但是问题有又来了。

然后问题解决了,但是之前的原始注册没法用了。

  1. 老李现在很烦,他现在快爆炸了,好麻烦,好多坑。但是他又暗暗窃喜,幸好老子是Java程序员,知道重入锁,要是别的没有重入锁语言的程序员肯定想不到可以用重入锁解决。

问题又得到圆满的解决,但是我们用了这么多技术,踩了这么多坑,我们是不是忘记了我们只是想注册保持userName唯一而已?这个要求很难吗?很难吗?为什么踩了那么多坑,用了那么多特殊的技术?改了12个版本,至于吗?

  1. 老李终于还是疯了,被不断变化的需求和不断出现的坑逼疯了。老李疯了以后,老板直接吧老李裁了,然后花高价把王二麻子挖了回来。通过这段时间的成长,王二麻子看着被改的面目全非的代码心里蹦出两个字垃圾。所有的问题好像都是引入redis锁开始,然后问题就像滚雪球一样的出,虽然总是可以解决,但是这里真的必须要用redis的锁吗?数据库写入操作不是已经有写锁了吗?而且这个写锁,基本有了redis锁以后,依旧不会还会有,2把锁?更安全吗?没有,更加麻烦倒是真的。然后王二麻子吧代码改成下面这个样子。

    查询用户并且拿到写锁,后面直到事务提交的锁才释放,不会有锁提前释放的问题,不会有上层事务的影响,锁少了一把,锁定后执行的逻辑也没有变多,代码还少了很多,逻辑也简单了,redis锁的效率会更高吗?不见得,正常影响效率的不是获取 锁的时间,而是等锁的时间和获取锁以后做的事情。用redsi锁,依旧会获取数据库写锁,只是拿到锁之后做的事情明显 for update 更加少。在可以命中索引的情况下,for update 也是行级锁。锁的力度不会比redis 指定key 大。

标签:userName,王二麻子,事务,用户名,删除,用户,问题,注册,怎样才能
From: https://www.cnblogs.com/cxygg/p/17019281.html

相关文章

  • layui 注册模板--并且提示注册成功--太爽了
    <!doctypehtml><htmlclass="x-admin-sm"><head><metacharset="UTF-8"><title>后台登录-X-admin2.2</title><metaname="renderer"content="webkit|ie-comp......
  • 7、SpringCloudAlibaba--注册中心Nacos
    Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。他是使用java编写。需要依赖java环境Nacos文档地址:https://nacos.io/z......
  • nacos注册中心单节点ap架构源码解析
    一、注册流程单nacos节点流程图如下:流程图可以知,Nacos注册流程包括客户端的服务注册、服务实例列表拉取、定时心跳任务;以及服务端的定时检查服务实例任务、服务实例更新......
  • 配置 mysql 与注册登录模块
    今天的笔记开始记录后端。大二的时候MySQL没清理干净,对MySQL有阴影了。希望这次可以顺利SpringBoot的角色是用来处理用户请求数据存到Mysql里面,Mysql本质上就是算法题里......
  • 怎样才能学以致用?
    俗话说得好:获取知识的唯一途径就是学习,而且是认真地、主动地学习。通常我们把学习分为三层境界:「读懂记住」,属于学习的“信息搬运工”过程!「读出己见」,从信息搬运工升级到......
  • 为什么会有用户名密码
    我们来思考一下用户名+密码的本质,通过用户名和密码我们可以去获取服务器上的资源,也就是用户名密码是获取资源的钥匙。如果我们需要去获取这份资源,只要拿到钥匙就行了,......
  • mysql的登录注册和连接他人数据库以及卸载
    mysql的登录参数:mysql-u用户名-p密码mysql的登录参数2:mysql-u用户名-p ,然后会提示你输入密码mysql的登录参数加连接他人数据库::mysql-u用户名-p密码-h要连接my......
  • dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zoo
    文章目录​​前言​​​​一、项目最后目录结构​​​​二、创建根项目dubbo-demo​​​​1.dubbo相关依赖​​​​2.pom.xml如下:​​​​三、创建api模块​​​​1.......
  • seata 分支事务注册及分支事务回滚时序图梳理
    1.业务时序图集成的seata版本为1.5.2。如图所示,创建三个微服务注册分支事务,整个流程中有四次DB操作,在最后执行异常抛出,用于演示分支事务注册及回滚时序。  2.各服务......
  • python-web:flask框架下的html实例——用户注册页面
    1、submit实现页面跳转,方法为get<h1>用户注册</h1><!--使用get方式提交,method为post/get,action保存提交到哪里--><formmethod="get"action="/do/reg......