首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

议论:用户操作唯一性管理

2012-11-06 
讨论:用户操作唯一性管理我们的项目是一个具有工作流特性的B/S系统;现在处于功能测试阶段,前几天一个同事

讨论:用户操作唯一性管理
我们的项目是一个具有工作流特性的B/S系统;现在处于功能测试阶段,前几天一个同事提出一个问题:

系统中的很多工作都必须有步骤的进行,比如,先做计划,然后实施,再查看结果。
系统中的用户权限分为浏览和操作,用户在模块中的权限是交错的,在一个模块可以操作而在另一个模块
只能浏览操作结果。

现在的情况是如果在同一时间有两个或多个对同一模块具有操作权限的用户在这一模块中进行操作的话,可能会引起
操作结果冲突的现象;比如A和B两个人都可以做发电计划,A、B两个人如果在同一时间都给电厂分配电量,那么电厂接到的
发电计划会冲突或者造成数据丢失!

现在我们想到的解决方法是

1.在数据库中给每一个模块建立一个操作步骤存储表,根据步骤标志位的判断解决冲突!

2.在服务器上作一个托盘,实时检测用户登录,当有一个用户在这一模块中进行操作时,进入这一模块的另一用户不管权限大小都
只分配浏览权限,并给用户以提示!

3.通过权限控制,两个对同一模块都具有操作权限的用户,谁先登录本模块谁就有操作权,后登录的只有浏览权;设定先登录用户
使用时间,时间一到再进行操作就需要重新登录,再进入时如果已经有用户在操作就给他分配浏览权限!


第一种方法实现最简单,但是数据交互量增加,交互频繁!
第二种方法实现起来应该比较麻烦,但是更能符合需求;
最后一种缺乏人性化!

请知各位是怎样解决这一问题的?请不吝赐教!
请积极拍砖! 16 楼 clamp 2006-12-31   daoger 写道clamp 写道奇怪,大家都觉得自己理解需求了吗?这么迫不及待的给技术解决方案啊……

我问个需求澄清问题:
是否存在以下这种情况,一个模块中有多个实例记录?
比如编辑计划
存在着多份计划,A/B两个用户都有编辑计划的权限,
在同一时刻A/B都能使用编辑计划这个功能,但是只能编辑不同的计划,而不能编辑相同的计划。



是这样的,每个人制定的计划都是根据各自对业务的理解而来的,一样的可能性不大!

还有一点就是,我们的功能基本全部实现了,现在正在由用户进行功能测试,项目再有几个月就要投运了!如果采取楼上几位的方法需要大量修改现有表结构的话肯定是不可取的!

昨天又问了一下项目经理,如果暂时没有好的解决方法,就只能从权限上控制,暂时每一个模块只有一个具有操作权限的用户!

唉!

各位以前的B/S项目中没遇到这样的需求吗?

看来是我的表达方式有点问题,再重复一下,有没有这样的情况:
A做了计划1,B做了计划2。
A可以改计划1,B可以改计划2,这两个操作可以同时进行
A也可以改计划2,B可以改计划1,这两个操作也可以同时进行
A/B不能同时改计划1
A/B不能同时改计划2





17 楼 daoger 2006-12-31   clamp 写道daoger 写道clamp 写道奇怪,大家都觉得自己理解需求了吗?这么迫不及待的给技术解决方案啊……

我问个需求澄清问题:
是否存在以下这种情况,一个模块中有多个实例记录?
比如编辑计划
存在着多份计划,A/B两个用户都有编辑计划的权限,
在同一时刻A/B都能使用编辑计划这个功能,但是只能编辑不同的计划,而不能编辑相同的计划。



是这样的,每个人制定的计划都是根据各自对业务的理解而来的,一样的可能性不大!

还有一点就是,我们的功能基本全部实现了,现在正在由用户进行功能测试,项目再有几个月就要投运了!如果采取楼上几位的方法需要大量修改现有表结构的话肯定是不可取的!

昨天又问了一下项目经理,如果暂时没有好的解决方法,就只能从权限上控制,暂时每一个模块只有一个具有操作权限的用户!

唉!

各位以前的B/S项目中没遇到这样的需求吗?

看来是我的表达方式有点问题,再重复一下,有没有这样的情况:
A做了计划1,B做了计划2。
A可以改计划1,B可以改计划2,这两个操作可以同时进行
A也可以改计划2,B可以改计划1,这两个操作也可以同时进行
A/B不能同时改计划1
A/B不能同时改计划2


做好的计划都存在数据库中,从库中读取计划时不区分哪个计划是哪个用户编辑的,正是这样就存在了A可以修改计划1,也可以修改计划2的问题!

计划下达之后就不能再修改,数据就被锁定了!计划下达前有操作权限的用户就可以对现有的所有计划进行修改!

我搜索了一下,这个问题的解决方法不多,呵呵!也可能是我搜索的不全面!我觉得这可能就是项目最初设计时的一个疏漏!

看来如果不能从技术上解决那就只能从业务上解决:工作分工! 18 楼 daoger 2006-12-31   XMLDB 写道按标志位来,在不远的将来就可以看到有一些谁都不能操作的数据了,哈哈

说得也对,一个标志位可能也解决不了问题,标志位多了就怕自己都搞乱了!唉! 19 楼 XMLDB 2006-12-31   在你的环境下,要把冲突分为两种:
1.多个计划的冲突
2.多个用户对同一个计划的冲突
第一个我上面已经说了,要使用带条件的更新,操作完后确认结果正确.在你的例子里如果超出可分配电量范围,很明显就需要返回业务异常提示用户.
第二个,和第一个方法一样,如果发现在更新后发现结果不是自己那个,则需要提示用户或让用户决定是放弃还是覆盖.
在一个操作里,都必须做上面两个检查.
20 楼 leelun 2006-12-31   daoger 写道leelun 写道用Hibernate的Version字段,控制每次只能由一人保存数据,如果出现Version冲突,就回滚并重新读取数据

一个步骤中有很多任务,一个任务也可以出现很多结果,这很多结果可能都是正确的;如:给电厂分配发电量,只要是在机组发电负荷之下的都可以认为是正确的!

我没用过Version字段,不知道是不是要修改数据库,即便是现在修改代码,工作量也不小啊!

再说这是依赖于hibernate,如果用其他映射框架呢?

查查用Hibernate的Version字段的用法,呵呵!
Hibernate的Version是个好东西,JPA的annotaion中都有,看到了都觉得亲切,呵呵。
Version是需要在表上增加一个字段,用于表示数据操作的版本,用户更新一条记录时,将Version字段的值加1。当更新前发现Version字段的值不等于自己记录中的值时,说明被别人更新过了,需要进行异常处理。
用Hibernate的Version的话自己不需要做什么代码改动,只需要改配置文件,表中增加Version字段。不用Hibernate的话,自己实现也不复杂。
不知道楼主对一个任务中的多个操作是如何做事务管理的,感觉每一个任务定一个事务,将多个原子操作包括起来,当一处原子操作有Version的冲突,整个任务全部回滚。不知道这样对你的代码改动大不大 21 楼 LucasLee 2006-12-31   我认为用Version不是解决这类问题的正确方法。
的确,Version是能解决数据并发修改的问题。
但关键看业务需求。
如果A用户,B用户一起做一个计划数据,搞了半天,B用户发现系统提示A用户已经做好了,你这不是浪费人力么?B用户肯定会说,为什么不让我在进入之前提示我A正在做了?或者我做了就提示A不要再做了。 22 楼 XMLDB 2006-12-31   拜托楼上看清楚人家的需求,电网调配只要不超过负荷就OK,管人家做多少计划呢.
不过,加上一个当前还有谁正在改同一个东西的功能还是很酷的, 又多一个卖点:这可是支持协同工作的产品哦 23 楼 clamp 2006-12-31   daoger 写道
做好的计划都存在数据库中,从库中读取计划时不区分哪个计划是哪个用户编辑的,正是这样就存在了A可以修改计划1,也可以修改计划2的问题!

你说这是一个问题,那需求是不是“A只能修改他自己编辑的计划1,不能修改计划2”

daoger 写道计划下达前有操作权限的用户就可以对现有的所有计划进行修改!

这是一个用户需求 还是 你们的系统现在是这么设计但不符合用户需求?
另外,不同用户的计划间是否可能有冲突?如果产生冲突,业务上如何解决这个问题?


daoger 写道看来如果不能从技术上解决那就只能从业务上解决:工作分工!

我认为这首先是一个业务问题。



24 楼 daoger 2006-12-31   Lucas Lee 写道我认为用Version不是解决这类问题的正确方法。
的确,Version是能解决数据并发修改的问题。
但关键看业务需求。
如果A用户,B用户一起做一个计划数据,搞了半天,B用户发现系统提示A用户已经做好了,你这不是浪费人力么?B用户肯定会说,为什么不让我在进入之前提示我A正在做了?或者我做了就提示A不要再做了。

这位老兄说得对,我们现在的需求就是这样的。既然要做这方面的功能处理,就要处理好,处理的人性话,尽量替用户着想!呵呵! 25 楼 daoger 2006-12-31   clamp 写道daoger 写道
做好的计划都存在数据库中,从库中读取计划时不区分哪个计划是哪个用户编辑的,正是这样就存在了A可以修改计划1,也可以修改计划2的问题!

你说这是一个问题,那需求是不是“A只能修改他自己编辑的计划1,不能修改计划2”

daoger 写道计划下达前有操作权限的用户就可以对现有的所有计划进行修改!

这是一个用户需求 还是 你们的系统现在是这么设计但不符合用户需求?
另外,不同用户的计划间是否可能有冲突?如果产生冲突,业务上如何解决这个问题?


daoger 写道看来如果不能从技术上解决那就只能从业务上解决:工作分工!

我认为这首先是一个业务问题。



1.只要有操作权限,他什么计划都可以修改!
2.由于项目要求的比较紧,当初设计的时候用户没有说明可能会有两个或两个以上的人同时操作一个模块,设计人员就没有考虑这个问题!现在项目不久之后就要投运了,用户才又提起这个需求的。
3.明确工作分工,A用户就只能对北方的电厂有操作权,B用户只能对南方的电厂有操作权,A B两个用户的业务划分不能有交集! 26 楼 newroc 2007-01-01   Lucas Lee 写道我认为用Version不是解决这类问题的正确方法。
的确,Version是能解决数据并发修改的问题。
但关键看业务需求。
如果A用户,B用户一起做一个计划数据,搞了半天,B用户发现系统提示A用户已经做好了,你这不是浪费人力么?B用户肯定会说,为什么不让我在进入之前提示我A正在做了?或者我做了就提示A不要再做了。
估计你有过CS程序的开发经验,如果你用PB开发实现这种要求很容易,bs应用,用这种方式简单想一下感觉很难或者不灵活。比如使用标志位,当A用户开始做计划,在数据库中记录A用户正在进行,这是后假设A不做了,关闭窗口(或者异常中断了),系统要怎么办,定时删除过期未更新的标志?还是不做处理,等待A用户下次有空了再来继续录入他的计划,在这个过程中其他用户统统不允许录入这个计划。这时候用户可能又要说了,我已经不录了,你为什么不让其他人录?你要怎么办? 27 楼 XMLDB 2007-01-01   daoger 写道Lucas Lee 写道我认为用Version不是解决这类问题的正确方法。
的确,Version是能解决数据并发修改的问题。
但关键看业务需求。
如果A用户,B用户一起做一个计划数据,搞了半天,B用户发现系统提示A用户已经做好了,你这不是浪费人力么?B用户肯定会说,为什么不让我在进入之前提示我A正在做了?或者我做了就提示A不要再做了。

这位老兄说得对,我们现在的需求就是这样的。既然要做这方面的功能处理,就要处理好,处理的人性话,尽量替用户着想!呵呵!
现在这个问题由技术问题变成了管理问题了,在多年前找解决多人checkout提交时出现需要merge version问题时就已经在CVS手册上看到,类似的版本冲突什么的是个管理问题,而不是技术问题。和daoge的问题类似,所以在工具上如果用户不是强烈要求的话,建议不要加上太多的限制而仅仅是增加一些提示,剩下的问题是客户的管理问题,划分区域是一个好的解决办法。 28 楼 clamp 2007-01-01   daoger 写道
1.只要有操作权限,他什么计划都可以修改!
2.由于项目要求的比较紧,当初设计的时候用户没有说明可能会有两个或两个以上的人同时操作一个模块,设计人员就没有考虑这个问题!现在项目不久之后就要投运了,用户才又提起这个需求的。
3.明确工作分工,A用户就只能对北方的电厂有操作权,B用户只能对南方的电厂有操作权,A B两个用户的业务划分不能有交集!

是需求问题,不是设计问题。
流程性的需求有一个重要检查点就是并发性。

如果用户答应你的工作分工建议,这个事情就好办了,不过我猜用户未必肯答应。
因为存在一个工作替代的需求,万一负责南方电厂的人有事,那么就需要别人来替代他的工作。

一个电厂在一个时间周期内(比如一个月/一年)应该只有一份计划,但是只要有权限的人都可以编辑,直到下达为止。

建议以下设计方案:
在计划创建时,确保有一个唯一标识字段,使得不会创建业务上互相冲突的计划。
在每份计划上加一个标志位(锁),采用checkout/checkin的机制,确保任一时刻只有一个人可以修改计划。
(需要处理异常断线的情况)
对于版本的控制:保存最新的修改后的计划和每一次的修改记录(修改人/修改时间/修改内容),一般不需要保存每一次的版本。
29 楼 jian7456 2007-01-02   我们也遇到这种问题,一般是记录的同步操作问题.
需求状况:操作一般分两步走,第一步显示记录列表,页面有ABC三条记录,
第二步选中其中一条后进入明细页面,提交后将记录转化为另种数据,并将记录的已转化标志设为真.
并发操作状况:有可能两个用户同时选中A记录,进入明细页面,再提交后会生成两条由A记录转化来的新数据,造成数据错误.

构思中的解决方法:在明细页面提交时是根据缓存中的数据生成新数据,如果在提交时根据数据主ID再查次数据库,判断标志位,已转化标志为真时抛异常,阻止提交.
存在问题:1,有些这种操作步骤的数据没有类似标志位.要改动比较麻烦.
2,对数据更新的并发操作可以定义出几种不同等级,孙卫琴的<精通HIBERNATE>中提到,什么可重复读,读未提交,读已提交等.一般更新问题要求并发性低,例如:ABC三条金额的数据,当用户甲操作A时,虽然用户乙也看到A,但不能选择A进行操作.这种情况应该是人为的加标志位上锁,即在选择进入时就操作数据库设标志位,有个麻烦是B/S结构中如何解锁,因为离开当前操作页面有许多方式,可以是点其他链接,也可以是关闭网页.

对于解锁问题的构思:因为判断解锁的情况太复杂,暂时考虑延时的方法,上锁后几分钟内无提交操作,自动解锁,允许用户乙选择数据A操作,问题是此时用户甲仍停留在操作页面,如何让甲的提交操作失败.这时发现锁的标志位应该涉及用户信息,考虑用用户主键当标志位,提交更新时判断标志位是否为当前用户的id,匹配的话才允许提交.

以上全是构思中的,无实践验证,不知对于更新的解锁方法有无更好的. 30 楼 daoger 2007-01-02   newroc 写道Lucas Lee 写道我认为用Version不是解决这类问题的正确方法。
的确,Version是能解决数据并发修改的问题。
但关键看业务需求。
如果A用户,B用户一起做一个计划数据,搞了半天,B用户发现系统提示A用户已经做好了,你这不是浪费人力么?B用户肯定会说,为什么不让我在进入之前提示我A正在做了?或者我做了就提示A不要再做了。
估计你有过CS程序的开发经验,如果你用PB开发实现这种要求很容易,bs应用,用这种方式简单想一下感觉很难或者不灵活。比如使用标志位,当A用户开始做计划,在数据库中记录A用户正在进行,这是后假设A不做了,关闭窗口(或者异常中断了),系统要怎么办,定时删除过期未更新的标志?还是不做处理,等待A用户下次有空了再来继续录入他的计划,在这个过程中其他用户统统不允许录入这个计划。这时候用户可能又要说了,我已经不录了,你为什么不让其他人录?你要怎么办?

确实要解决所有可能存在的问题都不容易;我们现在也没考虑的很深,就是先尝试着做怎样解排他锁的问题!

这位老兄说得问题,我觉得可以用事务来作;初步想法,还没开始搞!

节后再说,呵呵! 31 楼 daoger 2007-01-02   clamp 写道daoger 写道
1.只要有操作权限,他什么计划都可以修改!
2.由于项目要求的比较紧,当初设计的时候用户没有说明可能会有两个或两个以上的人同时操作一个模块,设计人员就没有考虑这个问题!现在项目不久之后就要投运了,用户才又提起这个需求的。
3.明确工作分工,A用户就只能对北方的电厂有操作权,B用户只能对南方的电厂有操作权,A B两个用户的业务划分不能有交集!

是需求问题,不是设计问题。
流程性的需求有一个重要检查点就是并发性。

如果用户答应你的工作分工建议,这个事情就好办了,不过我猜用户未必肯答应。
因为存在一个工作替代的需求,万一负责南方电厂的人有事,那么就需要别人来替代他的工作。

一个电厂在一个时间周期内(比如一个月/一年)应该只有一份计划,但是只要有权限的人都可以编辑,直到下达为止。

建议以下设计方案:
在计划创建时,确保有一个唯一标识字段,使得不会创建业务上互相冲突的计划。
在每份计划上加一个标志位(锁),采用checkout/checkin的机制,确保任一时刻只有一个人可以修改计划。
(需要处理异常断线的情况)
对于版本的控制:保存最新的修改后的计划和每一次的修改记录(修改人/修改时间/修改内容),一般不需要保存每一次的版本。


建议不错!

项目上个月底刚进行完一次联调,用户现在还没空管这方面的事情那,呵呵!不过以后肯定会说的! 32 楼 clamp 2007-01-02   jian7456 写道我们也遇到这种问题,一般是记录的同步操作问题.
需求状况:操作一般分两步走,第一步显示记录列表,页面有ABC三条记录,
第二步选中其中一条后进入明细页面,提交后将记录转化为另种数据,并将记录的已转化标志设为真.
并发操作状况:有可能两个用户同时选中A记录,进入明细页面,再提交后会生成两条由A记录转化来的新数据,造成数据错误.

构思中的解决方法:在明细页面提交时是根据缓存中的数据生成新数据,如果在提交时根据数据主ID再查次数据库,判断标志位,已转化标志为真时抛异常,阻止提交.
存在问题:1,有些这种操作步骤的数据没有类似标志位.要改动比较麻烦.
2,对数据更新的并发操作可以定义出几种不同等级,孙卫琴的<精通HIBERNATE>中提到,什么可重复读,读未提交,读已提交等.一般更新问题要求并发性低,例如:ABC三条金额的数据,当用户甲操作A时,虽然用户乙也看到A,但不能选择A进行操作.这种情况应该是人为的加标志位上锁,即在选择进入时就操作数据库设标志位,有个麻烦是B/S结构中如何解锁,因为离开当前操作页面有许多方式,可以是点其他链接,也可以是关闭网页.

对于解锁问题的构思:因为判断解锁的情况太复杂,暂时考虑延时的方法,上锁后几分钟内无提交操作,自动解锁,允许用户乙选择数据A操作,问题是此时用户甲仍停留在操作页面,如何让甲的提交操作失败.这时发现锁的标志位应该涉及用户信息,考虑用用户主键当标志位,提交更新时判断标志位是否为当前用户的id,匹配的话才允许提交.

以上全是构思中的,无实践验证,不知对于更新的解锁方法有无更好的.

锁肯定是要记录用户信息的。
由于异常断线或其他原因造成不能正常解锁是比较麻烦的。

我们以前采用过这样一种异常解锁机制:
假设有A/B两个用户,A用户先操作,通过checkout操作,对某条记录加锁。
随后B用户操作,这时给B用户一个提示:“A用户正在操作,是否需要强行进入?”
(这里B用户要和A用户进行系统外的沟通)
B用户可以选择强行进入,这时就直接把A用户的锁强行替换为B用户的锁,A用户如果试图对此记录进行操作,就会得到一个类似的提示:“B用户正在操作,是否需要强行进入?”

用户一般都可以接受这种操作模式的。


33 楼 daoger 2007-01-04   clamp 写道jian7456 写道我们也遇到这种问题,一般是记录的同步操作问题.
需求状况:操作一般分两步走,第一步显示记录列表,页面有ABC三条记录,
第二步选中其中一条后进入明细页面,提交后将记录转化为另种数据,并将记录的已转化标志设为真.
并发操作状况:有可能两个用户同时选中A记录,进入明细页面,再提交后会生成两条由A记录转化来的新数据,造成数据错误.

构思中的解决方法:在明细页面提交时是根据缓存中的数据生成新数据,如果在提交时根据数据主ID再查次数据库,判断标志位,已转化标志为真时抛异常,阻止提交.
存在问题:1,有些这种操作步骤的数据没有类似标志位.要改动比较麻烦.
2,对数据更新的并发操作可以定义出几种不同等级,孙卫琴的<精通HIBERNATE>中提到,什么可重复读,读未提交,读已提交等.一般更新问题要求并发性低,例如:ABC三条金额的数据,当用户甲操作A时,虽然用户乙也看到A,但不能选择A进行操作.这种情况应该是人为的加标志位上锁,即在选择进入时就操作数据库设标志位,有个麻烦是B/S结构中如何解锁,因为离开当前操作页面有许多方式,可以是点其他链接,也可以是关闭网页.

对于解锁问题的构思:因为判断解锁的情况太复杂,暂时考虑延时的方法,上锁后几分钟内无提交操作,自动解锁,允许用户乙选择数据A操作,问题是此时用户甲仍停留在操作页面,如何让甲的提交操作失败.这时发现锁的标志位应该涉及用户信息,考虑用用户主键当标志位,提交更新时判断标志位是否为当前用户的id,匹配的话才允许提交.

以上全是构思中的,无实践验证,不知对于更新的解锁方法有无更好的.

锁肯定是要记录用户信息的。
由于异常断线或其他原因造成不能正常解锁是比较麻烦的。

我们以前采用过这样一种异常解锁机制:
假设有A/B两个用户,A用户先操作,通过checkout操作,对某条记录加锁。
随后B用户操作,这时给B用户一个提示:“A用户正在操作,是否需要强行进入?”
(这里B用户要和A用户进行系统外的沟通)
B用户可以选择强行进入,这时就直接把A用户的锁强行替换为B用户的锁,A用户如果试图对此记录进行操作,就会得到一个类似的提示:“B用户正在操作,是否需要强行进入?”

用户一般都可以接受这种操作模式的。




不错!你能说的再具体一些吗?包括实现方式什么的!谢谢! 34 楼 magice 2007-01-26   引用
锁肯定是要记录用户信息的。
由于异常断线或其他原因造成不能正常解锁是比较麻烦的。

我们以前采用过这样一种异常解锁机制:
假设有A/B两个用户,A用户先操作,通过checkout操作,对某条记录加锁。
随后B用户操作,这时给B用户一个提示:“A用户正在操作,是否需要强行进入?”
(这里B用户要和A用户进行系统外的沟通)
B用户可以选择强行进入,这时就直接把A用户的锁强行替换为B用户的锁,A用户如果试图对此记录进行操作,就会得到一个类似的提示:“B用户正在操作,是否需要强行进入?”

用户一般都可以接受这种操作模式的。

你这里依然没有解决如何处理异常中断造成的不正常解锁问题! 35 楼 xugq035 2007-01-27   magice 写道引用
锁肯定是要记录用户信息的。
由于异常断线或其他原因造成不能正常解锁是比较麻烦的。

我们以前采用过这样一种异常解锁机制:
假设有A/B两个用户,A用户先操作,通过checkout操作,对某条记录加锁。
随后B用户操作,这时给B用户一个提示:“A用户正在操作,是否需要强行进入?”
(这里B用户要和A用户进行系统外的沟通)
B用户可以选择强行进入,这时就直接把A用户的锁强行替换为B用户的锁,A用户如果试图对此记录进行操作,就会得到一个类似的提示:“B用户正在操作,是否需要强行进入?”

用户一般都可以接受这种操作模式的。

你这里依然没有解决如何处理异常中断造成的不正常解锁问题!

其实我觉得既然既然需要系统外沟通,强行进入这个功能还是屏蔽比较好,让他自己退出比较安全。
对于异常解锁,可以设定为锁定人/系统管理员解锁。

热点排行