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

花歌 发布于 2017/06/20 14:24
阅读 228
收藏 1

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

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

加载中
0
sixliu
sixliu

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

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

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

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

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

0
DeMoNHaDeS
DeMoNHaDeS

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

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

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

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

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

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

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

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

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

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

1.加锁

2.加事务控制

3.异常捕获与处理

工作不满一年吧

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

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

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

0
d
dwcz

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

返回顶部
顶部