【问题标题】:SQL insert statement executed twiceSQL插入语句执行了两次
【发布时间】:2012-01-11 19:44:57
【问题描述】:

防止用户双击或刷新页面会导致执行两次SQL插入语句的最佳方法是什么,我尝试在单击后禁用该按钮,但结果并不是很好。我期待可以从代码隐藏中做到这一点。更像是 SQL 提交和回滚

【问题讨论】:

    标签: c# asp.net sql insert sqlcommand


    【解决方案1】:

    或许PRG wikipedia article可以帮到你:

    Post/Redirect/Get (PRG) 是 Web 开发人员常用的设计模式 帮助避免某些重复的表单提交并允许用户代理 使用书签和刷新按钮更直观地表现。

    【讨论】:

    • PRG 不会阻止由于双击或长时间运行请求期间的页面刷新而导致的多个表单提交(例如,在发出“重定向”响应之前)。 OP 要求一种可以防止双击重复的方法,而不必只是在一切完成后刷新页面。
    • @AlexNorcliffe,感谢您的澄清。我会保留答案,以便人们可以阅读您的评论。 +1
    【解决方案2】:

    如果你想防止这种情况发生,你需要服务器知道当前用户已经开始了一个动作,并且在满足一个条件之前不能再次开始。

    您需要能够在众多可能访问您网站的用户中识别出该用户。这是最简单的使用 SessionState 完成的,但是如果您不需要 SessionState 并且希望大规模扩展您的应用程序,则可以使用一个简单的随机 cookie 来识别用户,作为您用于将项目放入服务器缓存。

    假设您使用了 SessionState。您会执行以下操作(伪):

    public void StartAction()
    {
      var inProgress = HttpContext.Current.Session["actionInProgress"] as bool;
      if (!inProgress)
      {
         try
         {
            HttpContext.Current.Session["actionInProgress"] = true;
            MySqlController.DoWork();
         }
         finally
         {
            HttpContext.Current.Session["actionInProgress"] = false;
         }
      }
    }
    

    以上不考虑以下情况:

    • finally 块中捕获异常和/或关闭任何连接
    • 由于您的客户端的下一次点击而将后续操作排队(如果操作已经在进行中,此伪代码只会返回)
    • 我选择了最简单的解决方案,但实际上更好的做法是将其包含为异步运行的服务,这样您就可以监控进度,既有益于用户,又可防止多个并行进程。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      相关资源
      最近更新 更多