论坛首页 Java企业应用论坛

多人操作数据的处理策略--讨论

浏览 18503 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-25  
我们的方案是即使有很多人都有权限处理这个单子,同时也只能有一个去处理,加个签收就行了,最简单.
0 请登录后投票
   发表时间:2011-05-25  
songlixiao 写道
1. 数据库表增加一个时间戳字段。
2. 查询显示数据时,将世界戳字段查询出,并带到表单中。
3. 表单修改提交后,时间戳字段一同提交,保存前校验此数据时间戳是否与数据库一致,不一致说明已经被别人修改,不允许执行操作。
4. 如果时间戳一致,将数据的时间戳赋予当前时间,并保存到数据库。

原则是所有人都可以查询,但是修改则只有在最后一个版本上修改的才算有效。


+1
0 请登录后投票
   发表时间:2011-05-25  
songlixiao 写道
1. 数据库表增加一个时间戳字段。
2. 查询显示数据时,将世界戳字段查询出,并带到表单中。
3. 表单修改提交后,时间戳字段一同提交,保存前校验此数据时间戳是否与数据库一致,不一致说明已经被别人修改,不允许执行操作。
4. 如果时间戳一致,将数据的时间戳赋予当前时间,并保存到数据库。

原则是所有人都可以查询,但是修改则只有在最后一个版本上修改的才算有效。


如果是多个用户同一时间内都在查询这个订单,这样会造成大家谁都提交不了,一直疯狂查询这个订单,疯狂的争锁。
0 请登录后投票
   发表时间:2011-05-25  
spell 写道
唉,这个是糟糕的设计导致的问题,有一些东西做出来是给一个人用的,不是大家可以一起用的。包括现在的很多商城,其实都有楼主所说的这个问题。

我的解决办法是,谁要处理特定的任务,先申领这条任务,每个人只可以处理自己申领或者主管分配给自己的任务,那不就OK了吗?从业务上彻底解决这个问题。表结构方面,增加user_id,处理情况等。刚开始user_id为空,分配给谁,这个user_id就记谁的,处理的时候先判断任务的user_id是不是目前登录的这个人,不是的话,不给处理。其实这个跟工作流的整合很有关系。


如果要主管分配任务才能修改任务,那就太慢了。客户打电话来,告诉你要取消订单,你还要先给主管说,让主管给你分配这个订单的任务,那客户不是要在一边凉快着呢。
如果是自己领取的话,那这个订单在没有被操作前就永远属于你自己,别人都改不了了,如果领取任务的人太忙、或者走开了,那这个任务别人就改不了,直到她操作了或者退掉任务。
如果同一个客户连接打来两个电话,第一次要求修改,第二次要求取消,两次接电话的客服几乎不会是同一个,这样第一个客服还没操作只是领取了订单任务,而第二个客服想做操作就没法弄了。

我比较赞同在使用内存map,作为锁的依据。
0 请登录后投票
   发表时间:2011-05-25  
aaa5131421 写道
感觉上面有些人想的太复杂了
其实这个问题就是个并发的悲观锁的问题
你update之前肯定需要select by id的吧,这时候 加上for update 不就可以了么,让这个方法序列化执行。
此时你再update 的时候就不会出现effect 0 rowcount的情况了。因为此时只有当前线程可以修改或者删除this row,其他人想做修改或删除操作,必须要等你完事才可以继续。其他线程是阻塞状态。

这时如果for update 没有成功,也就是在for update之前就已经被被人删掉的情况,你需在for update 这句下面做一个判断,如果select 出来为null,就throw 个 exception出去,展示异常页面给客户就行了。这样就完美了。



如果你select by i 的时候 加上for update,那第二个用户请求这个id数据的时候就会没响应,一直等待,直到第一个人执行完成为止。如果这样你的结果和本来有啥区别吗?还让第二个用户出现无限等待的状况。
0 请登录后投票
   发表时间:2011-05-25  
kimmking 写道
乐观锁,悲观锁


正解
0 请登录后投票
   发表时间:2011-05-25  
<prop key="add*">PROPAGATION_SUPPORTS,-Exception</prop>
				<prop key="modify*">PROPAGATION_SUPPORTS,-Exception</prop>
				<prop key="remove*">PROPAGATION_SUPPORTS,-Exception</prop>
0 请登录后投票
   发表时间:2011-05-26  
codermouse 写道
songlixiao 写道
1. 数据库表增加一个时间戳字段。
2. 查询显示数据时,将世界戳字段查询出,并带到表单中。
3. 表单修改提交后,时间戳字段一同提交,保存前校验此数据时间戳是否与数据库一致,不一致说明已经被别人修改,不允许执行操作。
4. 如果时间戳一致,将数据的时间戳赋予当前时间,并保存到数据库。

原则是所有人都可以查询,但是修改则只有在最后一个版本上修改的才算有效。


+1

和 hibernate 乐观锁差不错。
0 请登录后投票
   发表时间:2011-05-26  
不知云 写道
aaa5131421 写道
感觉上面有些人想的太复杂了
其实这个问题就是个并发的悲观锁的问题
你update之前肯定需要select by id的吧,这时候 加上for update 不就可以了么,让这个方法序列化执行。
此时你再update 的时候就不会出现effect 0 rowcount的情况了。因为此时只有当前线程可以修改或者删除this row,其他人想做修改或删除操作,必须要等你完事才可以继续。其他线程是阻塞状态。

这时如果for update 没有成功,也就是在for update之前就已经被被人删掉的情况,你需在for update 这句下面做一个判断,如果select 出来为null,就throw 个 exception出去,展示异常页面给客户就行了。这样就完美了。



如果你select by i 的时候 加上for update,那第二个用户请求这个id数据的时候就会没响应,一直等待,直到第一个人执行完成为止。如果这样你的结果和本来有啥区别吗?还让第二个用户出现无限等待的状况。

等待的时间只是这个业务逻辑方法执行的时间,最大也只有几十毫秒而已,而且这个冲突的情况并不常出现,只是在当两个客户都同时点的时候才会出现的情况。这种情况下对客户的体验完全没有影响。说白了,这就是hibernate的悲观锁实现方式,当然,你也可以用乐观锁去做,当用乐观锁的时候,需要注意一点,如果你的业务逻辑操作中有任何一步无法回滚,就不能用乐观锁。比如你再业务逻辑中调用的第三方系统,乐观锁只能回滚数据库,回滚不了其他东西。
0 请登录后投票
   发表时间:2011-05-26  
kimmking 写道
乐观锁,悲观锁


+1

用乐观锁的时候,要向避免楼主的问题,可以在编辑的时候添加一个锁定按钮
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics