ASP.NET并发会话最佳实践

3

用户A登录票务管理系统以编辑"SomePage.aspx"上的内容。

30秒后,用户B登录以编辑"SomePage.aspx"上的相同票务。

在三层架构中,通知每个用户有其他人正在修改相同内容的最佳实践是什么?

5个回答

8
在像HTTP这样的请求/响应系统中,没有太多关于用户当前正在做什么的概念。你可以通知他们有人在“最近两分钟内”打开了工单以供编辑(甚至在这种情况下防止他们打开它),但是用户A可能会编辑半个小时——除非你也禁止了这种情况。你可以记录你认为用户A已经有效地“获得”了该项进行编辑的事实,但是对于Web应用程序来说,没有什么可以阻止用户走开并且从未保存或取消。

在考虑技术解决方案之前,我建议先思考一下技术上的限制(基本上是Web的异步和请求/响应性质),然后确定所需的行为。一些常见的行为包括:

  • 第一个编辑者胜出(告诉第二个编辑者他们的更改已被拒绝)
  • 第二个编辑者胜出(覆盖第一个编辑 - 告诉第一个编辑者为时已晚)
  • 合并(根据内容可能极其困难和/或不可能)。这可能是自动的或手动的(由第二个编辑者完成)。
  • 防止第二个人在您认为第一个人可能正在编辑时进行编辑(由于第一段提到的问题,对于Web应用程序来说很少合适)

你错过了悲观并发(即锁定,以使用户B甚至不被允许开始编辑过程)。 - Brad Wilson
悲观并发可能是一种选择,但在像HTTP这样的断开连接的环境中,它可能非常难以维护。您必须强制不断地通知服务器有关用户屏幕当前状态的信息。多选项卡场景也是需要解决的问题。 - Salamander2007
@Brad:我会把这看作是“甚至防止他们在这种情况下打开它”的一部分——请注意,我并不试图解决如何实现结果,只是“在开始编码之前确定您想要发生什么”。 - Jon Skeet
@Brad:在第一段中添加了更多信息,并添加了第四个要点以更全面地涵盖此内容。 - Jon Skeet
有一些关于“先编辑者获胜”的变体选项,允许第二个编辑者手动合并。 - Timbo

2

例如,Roundup使用乐观并发方法:当您提交更改时,您可能会看到一个警告,提示有人在您之前进行了更改,并附带一个链接到显示他们更改的页面。您可以单击“提交”以继续进行更改,或编辑表单中的值,然后再提交。

对于票务系统来说,这种方法效果还不错,因为票务系统上很少有共享状态--主要是您附加到消息日志(或者相似的地方),所以两个消息会一个接一个地添加。


1

我在这方面经验不是很丰富,但如果我需要做类似的事情,我会在工单表上创建一个名为EditingBy的新字段,并添加默认值“0”。

当用户调用TicketID = 897时,查询应该像这样:

SELECT * FROM Tickets WHERE TicketID = 897; 
UPDATE Tickets SET EditingBy = @UserID WHERE TicketID = 897;

在代码中,您可以查看EditingBy是否大于0,如果是,则可以警告UserB,UserA(您知道UserID)正在编辑票证,就像SO在某人发布答案并且您正在编写自己的答案或者当您获得新徽章时所做的那样。

提交更新票证时,您可以将该字段更新回0。

请注意,用户可能会进入SomePage.aspx并离开而不执行任何操作,因此在body标记中使用javascript onUnload触发异步调用以将EdittingBy更新回0是一个好主意。

希望这给您提供了一些想法。

编辑: 如果无法编辑数据库,则始终可以在XML文件中记录EditingBy,只需保留TicketID和UserID,并检查TicketID是否在XML中,而不是查找它是否大于0。


我不确定javascript的onUnload事件是否可靠,能否有其他人确认或驳斥? - CJM
<html> <head> </head> <body onunload="alert('触发了onunload事件')"> 以任何方式离开页面 </body> <html> - balexandre

1
我发现防止乐观锁最好的方法是在数据库中添加一个称为时间戳(SQLTimeStamp)的字段。该字段维护表中每个记录的唯一值。当用户A查询编辑表时,将SQL时间戳值存储在会话中。如果用户B在用户A之前查询并更新相同的记录,则SQL时间戳值将更改。如果现在尝试存储已编辑的值,则首先检查会话标记是否与数据库上当前时间戳相同,如果时间戳不同,则提示用户有人修改了记录。
这是我用于网络应用程序的解决方案。

0
我假设你在谈论一个类似于帮助台工单的东西,只有一个用户应该在同一时间内处理它。在这种情况下,当第一个用户“签出”时,工单的状态应该改变。

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