【问题标题】:What's the best method to stop duplicate inserts into the database停止重复插入数据库的最佳方法是什么
【发布时间】:2010-10-20 03:30:31
【问题描述】:

我有一个使用 asp.net、c#、sql server 和 linq to sql 的论坛应用程序。它受到多次插入的影响,我认为当按下插入按钮时,也可能在刷新浏览器或单击返回时。

什么是最全面的方法,或防止这种情况的方法。

更新: 我目前在插入文本后使用 response.redirect。 我认为在阅读回复后,正确的方法可能是立即使用 javascript 禁用该按钮? 然后在表单上的隐藏字段(或会话?)上保存唯一值。在数据库中为这个值创建一个字段,然后对照这个字段检查这个唯一值?

谢谢

【问题讨论】:

  • 受苦?你有并发,这很痛苦?哦,我的。

标签: c# asp.net sql sql-server linq-to-sql


【解决方案1】:
  1. 为每个页面分配一个UNIQUE cookie 或隐藏控件
    • 在您的表中创建一个 UNIQUE 字段来保存此 cookie 或控件值。
    • 如果使用相同的 cookie 插入记录,INSERT 将失败,您可以处理(或忽略)这种情况。

【讨论】:

  • 用临时令牌使数据库表变得混乱,尽管解决方案是正确的,但您只需要在会话(服务器端)而不是数据库上存储活动令牌 - 一旦插入,从会话中删除令牌.
【解决方案2】:

当我有一个插入或更新的页面时,我通常会在更新完成后执行 Response.Redirect 到另一个页面,即使您只是 Response.Redirect 到同一页面。这样,如果页面被刷新,您就不会重新发布您的数据。

【讨论】:

  • 好答案。通常也值得立即禁用按钮以阻止人们双击
  • 我同意这是个好主意,但是,在插入数据库后,我想在同一页面上显示数据,事后看来,我可能应该将文本编辑器页面作为一个单独的页面,但我有它嵌入在页面上并在添加文本时隐藏/显示
  • @Stuart 您仍然可以执行 Response.Redirect 到完全相同的页面,这可以防止重复发布
  • 在检查代码时,会发生这种情况,但是问题仍然存在,我认为可能发生了一些事情。如果性能很差,由于客户端连接,在重定向之前多次按下按钮。也许我应该立即禁用该按钮,并在插入时结合检查唯一 cookie。这应该会捕获浏览器刷新吗?
  • @Stuart 是的,我相信我的混合体和 JeeBee 的答案会很棒,禁用提交按钮很常见,但在某些圈子中不受欢迎。
【解决方案3】:

请注意,您的问题并非真正特定于您的数据库。您在发送多个浏览器请求时遇到问题,您必须解决该问题。使用 Dave 上述的重定向模式或使用 Cookie 签名

一个例子可以在这里找到http://aspalliance.com/711_Preventing_Duplicate_Record_Insertion_on_Page_Refresh_or_Postback_of_a_Web_Form

【讨论】:

    【解决方案4】:

    使用主键或唯一约束,如果你不能这样做,我建议你使用新的 MERGE 语句,如果它不存在则插入或更新,如果它存在(不知道你的业务规则所以这可能不适用于您的情况)MERGE 是 SQL Server 2008 及更高版本

    【讨论】:

    • merge 听起来像是解决方案的一个很好的部分,但只有 sql 2005
    【解决方案5】:

    查看来自 SO'r Dave Ward 的名为 PostBack Ritalin 的 ASP.NET AJAX 控件。这可以帮助您为您的 javascript 禁用想法提供一个已经测试过的解决方案。

    【讨论】:

      【解决方案6】:

      为评论在表单中分配一个唯一的ID,并与评论一起记录在数据库中。如果不存在,请在执行插入之前检查具有该唯一 ID 的 cmets。

      要允许用户一次在一个活动的站点上获得多个回复,您可以最初在服务器端分配令牌,将其放入该用户会话上的活动发布令牌列表中,将其放入隐藏字段在评论表单上,并且仅当该令牌在会话列表中时才允许将表单提交插入数据库(并在成功插入数据库后将其从会话列表中删除)。 这样您就不必像上面那样将发布令牌存储在数据库中,这有点简单但简洁。

      【讨论】:

        【解决方案7】:

        在数据的自然键上放置唯一索引,以防止输入重复。如果需要,将其针对表的所有字段(除了任何面向日期的字段,它们将在插入时接收系统日期或仅由后端使用的字段,例如 insertby,其中包含执行人的用户 ID插入)除了id。

        【讨论】:

          【解决方案8】:

          从输入数据流的一列或多列中选择一个自然主键。使用这些列在表上声明主键约束。如果您已经对代理键有一个主键约束,并且您不想删除它,请改为在自然键上声明一个 UNIQUE 约束。

          当应用程序尝试向表中插入重复行时,这将导致错误。但是,您必须对应用程序进行编程以识别错误并做正确的事情。

          【讨论】:

          • 主键与提交的数据无关。代理键可以,但您不会将其用作主键。
          • 该表有一个主键,问题是如果单击插入按钮,一个单独的唯一条目会提交一个唯一的 ID
          • 主键意味着唯一的约束。主键可以位于您创建的某个自动编号列上,但也可以位于输入流中的一个或多个列上。试试看,你可能会喜欢!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-05
          • 2013-04-11
          • 1970-01-01
          • 1970-01-01
          • 2012-05-15
          • 1970-01-01
          相关资源
          最近更新 更多