并发ASP.NET会话最佳实践

时间:2008-10-24 07:29:51

标签: asp.net session concurrency

用户A登录故障单管理系统以编辑“SomePage.aspx”

上的内容

用户B在30秒后登录以编辑“SomePage.aspx”

上的相同故障单

用于通知每个用户其他人正在修改相同内容的一些最着名的实践(在3层体系结构中)是什么?

5 个答案:

答案 0 :(得分:7)

在像HTTP这样的请求/响应系统中,没有太多关于用户当前正在做什么的概念。您可以通知他们其他人在最近两分钟内打开了机票进行编辑(或者甚至阻止他们在这种情况下打开它),但是用户A可以编辑半小时 - 除非您也禁止这样做。您可以记下这样一个事实,即您认为用户A已经有效地“获取”了该项目进行编辑,但是使用网络应用程序时,没有什么可以阻止用户离开计算机而不会保存/取消。

在考虑技术解决方案之前,我建议考虑技术限制(基本上是Web的异步和请求/响应性质)并计算出所需的行为。一些常见的行为是:

  • 首先编辑胜利(告诉第二编辑,他们的更改已被拒绝,基本上)
  • 第二次编辑获胜(覆盖第一次编辑 - 告诉第一位编辑为时已晚)
  • 合并(可能非常困难和/或不可能,具体取决于内容)。这可以是自动的或手动的(在第二个编辑器方面)。
  • 在您认为第一个人可能正在编辑时阻止第二个人进行编辑(由于第一段中提到的问题,很少适合网络应用)

答案 1 :(得分:2)

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

这适用于票证系统,因为票证上的共享状态很少 - 大部分是附加到消息日志(或等效的),因此这两条消息会一个接一个地添加。

答案 2 :(得分:1)

我对此并不是很有经验,但如果我需要这样做,我会在Ticket Table上的数据库上创建一个名为 EditingBy 的新字段,并添加一个默认值' 0' 。

当用户调用TicketID = 897时,查询应该是:

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

然后在代码中,您会看到EditingBy是否大于0,您可以警告UserB UserA(您知道UserID)正在编辑故障单,就像有人发布答案并且您正在编写您的答案时那样,或者当例如,你会得到一个新徽章。

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

并建议用户可以输入SomePage.aspx而不做任何事情,因为body标签中的 javascript onUnload 将触发异步调用以将EdittingBy更新回0会是一个想法。

跳,这让你知道这样做。

<强>编辑: 如果你不能编辑数据库本身,你可以随时将EditingBy记录在XML文件中,只需保留TicketID和UserID,而不是查找它是否大于0,只需检查TicketID是否在XML中。

答案 3 :(得分:1)

我发现阻止乐观并发的最好方法是在数据库中添加一个名为timestamp的字段,例如:SQLTimeStamp。此字段为表中的每个记录维护唯一值。当用户A查询表进行编辑时,将sqltimestamp值存储在会话中。如果用户B在用户A之前查询并更新相同的记录,则sql时间戳值会发生变化。如果用户A现在尝试存储编辑的值,请首先检查会话标记是否与数据库中的当前时间戳相同,如果时间戳不同,则提示用户有人修改了该记录。

这是我用于Web应用程序的解决方案。

答案 4 :(得分:0)

我假设您正在谈论帮助台票或者是一些非常有用的东西,其中一次只有一个用户应该使用它。在这种情况下,当第一个用户将其签出时

,票证的状态应该会发生变化