我有一个表有三个记录的字段.如果用户要从表中编辑记录,则不允许其他用户同时编辑该记录.我可以采取什么样的步骤来实现这一目标?
来自桌面应用程序背景的很多人都会想知道如何在Web应用程序中完成此操作.
桌面世界中的一种方法是在行上有一个布尔列,表示正在编辑它,以及由谁编辑.您当然可以使用Web应用程序执行此操作,但这是一种非常糟糕的方法,因为如果用户访问"编辑"页面,将记录置于锁定状态,然后离开页面,它将永远处于锁定状态.您没有明确的方法来告诉用户仍然没有打开编辑页面.
航空公司预订方法是上述的变体,但您也可以使用LockedUntilUtc,它是一个日期时间,表示记录锁定的时间.假设Bob访问了一个记录页面,当从GET操作提供apge时,您还设置了锁定标志,并将LockedUntilUtc设置为10分钟.5分钟后,Sarah访问该页面,但由于您检查了LockedUntilUtc并且目前处于未来状态,因此出现"当前已锁定"错误.再过6分钟(自锁定以来总共11分钟)并且有人访问该页面并且LockedUntil现在已经过去,因此您将锁定给新用户.
这似乎是一个合理的妥协,但它充满了肯定会让用户感到沮丧的问题.首先,没有简单的方法来排队需要访问权限的用户来编辑记录.Sarah可以尝试10次,然后就在它经过10分钟时,Jimmy访问了该页面,因为他是锁定过期后的第一个人,他抓住了下一个锁定而Sarah没有机会.Sarah打电话给你的服务台,说她等了10分钟才能锁定到期,现在已经15分钟了,她仍然无法访问该页面.你的服务台可能会怀疑她真的等了整整10分钟,然后来回.
您还必须为当前拥有锁定的人实施客户端计时器/显示器,以便他们知道在它们到期之前还剩多少时间.
在大多数情况下,这是正确的方法.实际上你根本没有以任何方式锁定记录.相反,许多用户可以访问编辑页面.当他们保存编辑时,表单包括原始值和新编辑的值.服务器将比较表单中的原始值与数据库中的当前值,以查看是否存在临时编辑.
在原来的值是从过去(当Bob最初访问的编辑页面)的一些点.该电流值是来自现在.在过去和现在之间,如果Sarah也访问了编辑页面,并成功保存了对数据库值的更改,那么Bob的原始值将与数据库中的当前值不同.因此,当Bob尝试保存其更改时,服务器将看到其原始值与DB中的当前值不同,并抛出错误.您需要决定如何处理这种情况.通常,您让用户知道其他人已经编辑过页面,并刷新页面,然后他们就会丢失编辑内容.实体框架支持乐观并发.
您还可以让客户端偶尔使用原始值ping服务器,以便服务器可以检查您的页面是否过时(即其他用户更改了某些内容)并弹出消息.这通过向用户提前通知另一用户已编辑页面来改善用户体验.因此,他们在进行编辑方面并没有走得太远,反正他们将会失败.他们还可以从浏览器中记录/复制/粘贴他们的编辑内容,以便刷新页面并参考他们更改的内容.
SQL Server中有一个Timestamp列,它可以与Entity Framework协同工作,以降低检查更改所涉及的开销.这样您就不需要在每个客户端中保留原始值的整个记录并将其传回来:http://www.remondo.net/entity-framework-concurrency-checking-with-timestamp/
我们使用的一种方法是ajax'ify每个字段,并立即提交到单个字段的编辑.这是使用名为x-editable的jquery库完成的.用户编辑单个字段,确认编辑,并将该值发送到服务器.如果要检查整个记录的更改,或者只检查单个字段,可以将其与乐观并发相结合.如果检测到更改,则拒绝编辑并刷新页面.这对于用户来说可以是更友好的体验,主要是因为用户在编辑单个字段时立即获得"另一个用户编辑的页面"错误.这可以防止他们浪费大量时间来编辑大量字段,但却发现他们的编辑遭到拒绝,他们不得不重新编辑所有编辑内容.相反,他们编辑单个字段,获取错误,页面刷新,他们只需要重复那一个字段编辑并从那里继续.
http://vitalets.github.io/x-editable/demo-bs3.html
| 归档时间: |
|
| 查看次数: |
1391 次 |
| 最近记录: |