如果超时失败,C#重试Sql查询

时间:2016-04-20 03:20:06

标签: c# sql-server

我的查询超时并导致失败。重试执行查询的最佳方法是什么?

我在执行查询之前验证连接是否已打开。但是,由于任何给定时间的服务器负载,可能需要<1分钟到5分钟以上。我想扩展CommandTimeout,但我不相信这是真正的方法。

这是我的SQL查询代码。感谢所有的帮助。

    private static void ExecuteQuery(string connectionString, string query)
    {
        SqlConnection connection = new SqlConnection(connectionString);
        DataTable output = new DataTable();

        try
        {
            //create new SqlAdataAdapter
            SqlDataAdapter command = new SqlDataAdapter {SelectCommand = new SqlCommand(query, connection)};

            //connect to Sqldb
            connection.Open();

            //validate connection to database before executing query
            if (connection.State != ConnectionState.Open) return;
            Console.WriteLine("Connection successful\nExecuting query...");

            //set connection timeout
            command.SelectCommand.CommandTimeout = 200;

            //create new dataSet in order to input output of query to
            DataSet dataSet = new DataSet();

            //fill the dataSet
            command.Fill(dataSet, "capacity");
            DataTable dtTable1 = dataSet.Tables["capacity"];

            Console.WriteLine("There are " + dtTable1.Rows.Count + " clusters within the capacity anlaysis.");

            output = dtTable1;
        }
        catch (Exception e)
        {
            Console.WriteLine("Unable to execute capacity (all records) query due to {0}", e.Message);
        }
        finally
        {
            connection.Close();

            Declarations.NumOfClusters = output.Rows.Count;
            Declarations.finalIssues = Issues(output, 2m, 20, true);

            Console.WriteLine("\n---------------Successfully Created Capacity DataSet---------------\n");
        }
    }

4 个答案:

答案 0 :(得分:2)

使用Palmer库:https://github.com/mitchdenny/palmer

  Retry.On<Exception>().For(TimeSpan.FromSeconds(15)).With(context =>
  {
    // Code that might periodically fail due to some issues.
       ExecuteQuery(string connectionString, string query)
       if (contect.DidExceptionLastTime)
           Thread.Sleep(200); // what ever you wish
   });

请参阅github页面上的API。例如,您可以检查异常的上下文,并在发生异常时决定休眠一段时间。 您可以在更具体的例外情况下重试。 你可以永远尝试等等。

答案 1 :(得分:0)

重试操作的通用方法

 public static class Retry
    {
       public static void Do(
           Action action,
           TimeSpan retryInterval,
           int retryCount = 3)
       {
           Do<object>(() => 
           {
               action();
               return null;
           }, retryInterval, retryCount);
       }

       public static T Do<T>(
           Func<T> action, 
           TimeSpan retryInterval,
           int retryCount = 3)
       {
           var exceptions = new List<Exception>();

           for (int retry = 0; retry < retryCount; retry++)
           {
              try
              { 
                  if (retry > 0)
                      Thread.Sleep(retryInterval);
                  return action();
              }
              catch (Exception ex)
              { 
                  exceptions.Add(ex);
              }
           }

           throw new AggregateException(exceptions);
           }
        }

您现在可以使用此实用程序方法执行重试逻辑:

Retry.Do(() => SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1));

答案 2 :(得分:0)

我在asp.net web表单中编写了一个示例代码,运行了10次。

        static int noOfTries = 0;
        protected void Page_Load(object sender, EventArgs e)
        {
            function();
        }

        private void function()
        {

            try
            {

                if (noOfTries == 10) goto XX;
                noOfTries++;
                int a = 0;
                int b = 1 / a;


            }
            catch (Exception ew)
            {
                Response.Write(ew.Message + "<br/>");
                function();

            }
            XX:
            int c = 0;
        }

注意: 使用静态变量

时,它不是线程安全的

static int noOfTries=0 多线程执行可能不会像你一样工作,因为静态变量将在多线程中共享。

解决使用问题 Session["noOfTries"]

如果是多线程执行环境。

答案 3 :(得分:0)

以一种方式重新构造代码,以便它可以递归地调用查询,直到获得所需的结果。

例如

{{1}}

您可能希望合作程序能够尝试执行此操作来重试次数,以便为其提供一定的灵活性。

此外,如果您的查询花了这么长时间,您应该研究如何优化SQL Server数据库以借助视图/索引等减少执行时间。