开发者社区> 问答> 正文

三个看似简单但不容易解决的设计问题? 400 报错

三个看似简单但不容易解决的设计问题? 400 报错

1.A操作把一条记录状态改为1,B操作把状态改为2,这个记录可能在数据库里,也可能在内存里,不重要,就是可能存在多种状态,如果A操作先执行,B操作后执行,状态该是2,但如果因为网络延迟等原因,B操作先执行完成,那数据就被覆盖成了1,不符合现实情况,我只能控制其执行顺序,不能控制执行完成顺序,如何解决。
2.在方法中,A对象改变了一组属性,B对象改变了一组属性,那现在如果出现异常或返回值错误,整体操作失败,那执行完操作的属性如何回滚,还是这种设计就不合理,那该怎么设计。
3.用户注册的常见问题,查询用户名时,用户名可用,可这时候两人同时注册就都发到数据库了,数据库再唯一性出错返回了,大家都是怎么处理的,怎么加锁。

大家谈谈经验啊 万分感谢!

展开
收起
爱吃鱼的程序员 2020-05-29 20:15:22 832 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    1.第一个问题通过数据版本,也就是所谓的乐观锁解决。

    2.先写日志log,然后ack机制。其实很多这种方式被很多应用所用到比如mysql。

    3.用户注册本身这个功能不属于高频调用,所以性能上不需要考虑太多,直接悲观锁实现即可。而且这种可能性非常低,就算失败,那么返回给用户一个能理解的失败信息即可。

    ######回复 @sixliu : 谢谢回复 靠谱的回答真不多 我再等等看...######回复 @花歌 : 第二个 可能没太理解你的场景######谢谢咯~ 1和3可以,我看看还有什么别的方案,差不多也就这么做了,2的话 再考虑考虑吧 感觉还是有点不适用场景######

    三个问题,其实就是同一个并发的问题,

    ######

    都是并发中会出现的问题。

    1说的在内存里的情况,就是2。

    1说的在数据库中的情况,就是3。

    在数据库中,数据库自己会有锁来解决这个问题,遇到这种情况会修改失败,程序中捕获这种异常做处理返回给前台就可以了。

    在内存中,单机单进程单线程,会有顺序,因此没有问题。多机或多进程或多线程操作同一数据,会出现此问题。一种实现方式是加锁,相当于仿照数据库那样的实现,内存正在被修改时,其他的修改会被阻塞或者异常终止。另一种方式是通过队列实现顺序操作,所有的修改都发送到一个程序修改。

    ######让我想想,嗯 差不多,回答比较靠谱,谢了先 其实...我用的是nodejs 全异步操作,前面的数据库操作没完成,后面的也可以进入函数,如果网络延迟,就会造成执行完成顺序和开始执行顺序不一致... 等等想一会再问你哈######

    1. 是设计上的问题  两个操作如果有先后顺序  就得先后执行   一个操作完了之后再下一个操作   不可能明知道有一前一后 却还要非得一起

    2. 这个就是非常典型的数据库事务   就是保证多个不相关的操作的原子性  只要其中一个出问题就全部回滚  不存在有的成功有的失败  事务还是个挺复杂的东西   mongodb都还不支持事务  多服务器之间分布式的事务也是有些麻烦的  

    3. 同时的操作 数据库自己会进行锁的处理  对数据库来说还是一前一后    如果某个字段设置了唯一索引  那后面的那个必然会出错  代码里正常处理就可以了   所以用户名不唯一的处理有两个地方  一个是在插入之前  一个是在插入时抛出唯一索引异常      当然也可以在新建用户这一整个操作上加锁   全局同时只能有一个用户在新建  不过这样可能效率不高  

    ######问题1 现实情况就是这样 用户以为他的操作有顺序 但基于连接池 算是并发操作 即时不用池 那也是异步操作 不能保证顺序 所以只能考虑数据库锁 时间戳 问题2 还没到数据库呢... 只考虑多个内存中的对象操作 问题3 现在就是这样处理的######

    1.加锁

    2.加事务控制

    3.异常捕获与处理

    工作不满一年吧

    ######不好意思... 工作6年多了 开发经验10多年 问题1 暂时用乐观锁解决了 问题2 事务控制个毛线 问题你可能是没读清 内存中的几个对象而已 和数据库无关 就是事务也得自己实现 这话谁都会说 我想听的是 备忘录模式 这种... 到底怎么做能优雅点 还是我从需求设计上可能有问题 问题3 靠数据库唯一约束出错返回太暴力 现在就是这么做的 也可以数据库加锁 怕影响性能######

    1,update user set status=2 where status=3 and id=1;

    2,用户名设置唯一索引。

    ######

    可以用现在拷贝上操作,再合并的方法解决。1、按顺序合并。2、按状态合并。3、按索引合并。

    2020-05-29 20:15:24
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
典型业务逻辑漏洞挖掘 立即下载
代码未写,漏洞已出——谈谈设计不当导致的安全问题 立即下载
数据+算法定义新世界 立即下载