我的查询超时并导致失败。重试执行查询的最佳方法是什么?
我在执行查询之前验证连接是否已打开。但是,由于任何给定时间的服务器负载,可能需要<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");
}
}
答案 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数据库以借助视图/索引等减少执行时间。