论坛首页 Java企业应用论坛

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

浏览 18506 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-25  
如果你早一周提出此问题,那我上周五的面试通过的几率会大大的增加的,哎
0 请登录后投票
   发表时间:2011-05-25  
对于特别敏感的数据,建议使用存储过程加乐观锁。
0 请登录后投票
   发表时间:2011-05-25   最后修改:2011-05-25
goooooon 写道
update时候判断sql%rowcount,更新不为1,就抛错误,保证数据一致,ok了

正解
0 请登录后投票
   发表时间:2011-05-25  
如果一个系统的某资源对于a很重要,对于b不重要并且可以随意删除的话,这设计是何等的狗屎。a不会杀了b吧?另外删除的时候不要真删除,修改开关字段不就ok了?
0 请登录后投票
   发表时间:2011-05-25  
唉,这个是糟糕的设计导致的问题,有一些东西做出来是给一个人用的,不是大家可以一起用的。包括现在的很多商城,其实都有楼主所说的这个问题。

我的解决办法是,谁要处理特定的任务,先申领这条任务,每个人只可以处理自己申领或者主管分配给自己的任务,那不就OK了吗?从业务上彻底解决这个问题。表结构方面,增加user_id,处理情况等。刚开始user_id为空,分配给谁,这个user_id就记谁的,处理的时候先判断任务的user_id是不是目前登录的这个人,不是的话,不给处理。其实这个跟工作流的整合很有关系。
0 请登录后投票
   发表时间:2011-05-25  
Pessimistic Locking & Optimistic Locking..
但Optimistic可能不大复合LZ的情况...用Optimistic是意味着第二个修改的人会TransactionRollback
0 请登录后投票
   发表时间:2011-05-25  
railway 写道
yangyi 写道
railway 写道
yangyi 写道
railway 写道
rocketball 写道
szcs10138456 写道
小盆友们不用争了,先查询,加上乐观锁不就OK了。

这压根不是这个问题,主要是考虑后台操作人员工作重复,人家是通过这个统计工作量的


看到任务列表后,先把某笔任务申请下来(数据库表中记录申请人信息,便于统计工作量),申请成功则开始做该任务,如果不想做该任务,则可以释放,让别人去做。

这个是排它锁,和synchronized一样


这跟排它锁没什么关系,synchronized需要排队,而申请数据是将共用的数据申请为私有的数据,申请成功再进行操作,比如修改花了半个小时(由于是私有数据,别人无法操作,就不怕别人删除);
修改数据或删除数据时,带有自己的用户信息(SQL的where条件中加入用户信息)。


就锁的本质效用而言是一样的,都需要排队访问临界区。唯一的区别可能就是是否block



我觉得楼主的困境应该在于两点:

1、B操作的数据可能被其他人操作了(甚至删除了)
    此时的解决方法是使用乐观锁,可以使用时间戳或者UUID。

2、工作量统计问题
   比如,A、B两人同时去操作同一数据(假设是填写复杂的表单),A花了30分钟去修改,B看了数据后,觉得没用,花了20秒钟的时间删除了它,因为B先提交,所以提交成功了(删除成功),而A不知道,还在那里卖力地填写,等到A提交的时候,提交失败,受影响的记录为0(Query OK, 0 rows affected),数据未保存。
  对于A来说,浪费了30分钟的时间去做“无意义”的事(结果未提交成功),如果要统计工作量的话,A这笔业务是无效的,如果一天下来,A倒霉地碰到了很多这样的情况,那要抓狂了,当然这不是A的原因,是系统设计的问题。

还有你的是删除的人权限大,还是修改的人权限大,如果是修改的权限大,那在修改的时候不能删除,反过来就是修改的时候可以删除。

如果是电子商务后台,订单肯定不会真的删除,应该只会修改某个字段进行判断。要有操作人员的记录。

还有就是实际情况,麻烦的是修改的时候可以删除,那删除的之后如何能及时通知前台还在修改的人员,B/S目前可以用
异步轮询,C/S 可以用JMS之类异步通信。
0 请登录后投票
   发表时间:2011-05-25  
我之前做过一个跟LZ的需求类似的东西
首先我们的并发性肯定不高,最多也就100多人同时操作。
我们当时的要求是 有一个人在修改一个数据的时候 就锁住这个具体的url 比如 /action.update?sid=1,当修改完毕之后释放这个url,或者超过一段时间就自动释放这个url的锁
实现就是放一个全局的map,key是url,value是用户ID_开始锁的时间,就维护这个map,同一个用户先锁了一个url,如果他再点了其他的url那么就一处这个key-value,如果没点,等到其他的用户访问的时候就计算时间是否超时,如果超过就可以进入
不清楚 是否对你有帮助
0 请登录后投票
   发表时间:2011-05-25  
感觉上面有些人想的太复杂了
其实这个问题就是个并发的悲观锁的问题
你update之前肯定需要select by id的吧,这时候 加上for update 不就可以了么,让这个方法序列化执行。
此时你再update 的时候就不会出现effect 0 rowcount的情况了。因为此时只有当前线程可以修改或者删除this row,其他人想做修改或删除操作,必须要等你完事才可以继续。其他线程是阻塞状态。

这时如果for update 没有成功,也就是在for update之前就已经被被人删掉的情况,你需在for update 这句下面做一个判断,如果select 出来为null,就throw 个 exception出去,展示异常页面给客户就行了。这样就完美了。
0 请登录后投票
   发表时间:2011-05-25  
悲剧了 写道
用户故事如下:

电子商务后台管理,有多个客服人员可以操作同一个数据,当有的人正在对他进行修改的时候,其他人却觉得这个数据是垃圾数据,就直接删除了

如果是你,你在项目中如何处理这一小细节。

比如:当你载入订单修改的适合,有人已经把订单删除了,你去保存,不会有任何错误,反而操作成功

可以去数据库更新一个id不存在的字段,没有任何问题,只会
update  qqinfo set name='fdfd
' where id=90;

Query OK, 0 rows affected
Rows matched: 0  Changed: 0  Warnings: 0


我们目前策略如下:

对订单管理,很多工作人员都可以载入订单

特殊处理这个操作数据库的方法,设置一个字段--是否可用

可用才执行操作,操作的适合先把这个字段设为不可用

欢迎大家提出好的想法

搞什么鬼,你们这种业务也给删除操作?这些数据根本就不应该充许删除,这是需求和设计上的问题。
如果你用hibernate,会有两个关键字可以用来解决此类问题。timestamp和version number.是hibernate提供的,数据库并不需要有此字段。
如果没用hibernate,一样可以数据库用version number这样的机制实现。

0 请登录后投票
论坛首页 Java企业应用版

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