如何在ASP.NET应用程序中实现“悲观锁定”?

6
我希望从有经验的asp.net应用程序实现“悲观锁定”功能的人那里获得一些建议。以下是我正在寻找的行为:
1.用户A打开订单#313 2.用户B尝试打开订单#313,但被告知用户A已经独占地打开了订单X分钟。
由于我以前没有实现过此功能,因此我有几个设计问题:
1. 我应该将哪些数据附加到订单记录上?我正在考虑: - LockOwnedBy - LockAcquiredTime - LockRefreshedTime 2. 如果LockRefreshedTime < (Now - 10 min),则我会认为记录已解锁。
3. 如何确保锁定不会持续时间比必要时间长,但又不会意外地过期?
我对jQuery非常熟悉,因此可以使用客户端脚本来处理。这将是一个内部Web应用程序,因此我可以在使用带宽/循环方面相当自由。我还想知道“悲观锁定”是否是此概念的适当术语。
2个回答

8
听起来你已经完成了大部分工作。我认为你不需要LockRefreshedTime,它并没有什么用处。你可以使用LockAcquiredTime来判断锁是否过期。
另外,你需要确保使用事务。你需要将检查和设置锁的操作包装在一个数据库事务中,这样你就不会出现两个用户都认为自己拥有有效锁的情况。
如果你有需要在多个资源上获取锁的任务(即给定类型的多个记录或多种类型的记录),那么你需要在任何进行锁定的地方以相同的顺序应用锁定。否则,你可能会遇到死锁的情况,其中一段代码已经锁定了记录A并想要锁定记录B,而另一段代码已经锁定了B并正在等待记录A。
至于如何确保锁不会意外释放,请确保如果你有任何长时间运行的进程可能超过锁定超时时间,那么它在运行期间刷新其锁。
“显式锁定”这个术语也用于描述这种类型的锁定。

+1 棒极了的回答,谢谢。我会在24小时内不采纳答案,希望能得到更多的回复。 - Ken Browning
小心那些在午餐/度假时仍然让浏览器开着的人。考虑是否需要一些用户界面或管理器来打破其他人的锁定。(从经验中说出来的。) - Jason DeFontes

1

我已经手动完成了。

  • 将记录的主键存储到锁定表中,并将记录模式属性标记为编辑。
  • 当另一个用户尝试选择此记录时,指示用户只读记录。
  • 设置最长锁定记录时间。
  • 刷新已锁定记录的页面数据。虽然允许用户进行更改,但所有其他用户仅允许检查。

锁定表应具有类似于此设计:

User_ID, //who locked
Lock_start_Time,
Locked_Row_ID(Entity_ID), //this is primary key of the table of locked row.
Table_Name(Entity_Name) //table name of the locked row.

剩余的逻辑是你需要自己想出来的。

这只是一个想法,我在4年前应特定客户要求实现了它。之后没有人再要求我做类似的事情,所以我没有实现任何其他方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接