异步打开连接时重试策略不起作用
本文关键字:重试 策略 不起作用 连接 异步 | 更新日期: 2023-09-27 17:51:05
在我的应用程序中,我使用企业库Topaz(瞬态故障处理应用程序块)。我试图实现SqlConnection.OpenWithRetryAsync。但这行不通。我的意思是,当我放置断点时,它只在第一次命中并抛出异常。这是我试了这么快,
public static Task OpenWithRetryAsync(this SqlConnection connection, RetryPolicy retryPolicy)
{
return retryPolicy.ExecuteAsync(() =>
{
return connection.OpenAsync();
});
}
只是挖掘源代码,发现我得到一个SQL错误,这不是暂时的。我的错误代码是10065,错误是,
在建立到SQL Server的连接时发生了与网络相关或特定于实例的错误。未找到服务器或无法访问服务器。验证实例名是否正确,SQL Server是否配置为允许远程连接。(provider: TCP provider, error: 0 -试图对一个不可达的主机进行套接字操作)
当我跑的时候,
public static Task OpenWithRetryAsync(this SqlConnection connection, RetryPolicy retryPolicy)
{
return retryPolicy.ExecuteAsync(async () =>
{
try
{
await connection.OpenAsync();
}
catch(SqlException ex)
{
throw CreateSqlException(10060);// got it form http://blog.gauffin.org/2014/08/how-to-create-a-sqlexception/
}
});
}
那么我的重试策略就像一个魅力。
public bool IsTransient(Exception ex)
{
if (ex != null)
{
SqlException sqlException;
if ((sqlException = ex as SqlException) != null)
{
// Enumerate through all errors found in the exception.
foreach (SqlError err in sqlException.Errors)
{
switch (err.Number)
{
// SQL Error Code: 40501
// The service is currently busy. Retry the request after 10 seconds. Code: (reason code to be decoded).
case ThrottlingCondition.ThrottlingErrorNumber:
// Decode the reason code from the error message to determine the grounds for throttling.
var condition = ThrottlingCondition.FromError(err);
// Attach the decoded values as additional attributes to the original SQL exception.
sqlException.Data[condition.ThrottlingMode.GetType().Name] =
condition.ThrottlingMode.ToString();
sqlException.Data[condition.GetType().Name] = condition;
return true;
case 0:
if ((err.Class == 20 || err.Class == 11) && err.State == 0 && err.Server != null && ex.InnerException == null)
{
if (string.Equals(err.Message, Resources.SQL_SevereError, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
}
return false;
// SQL Error Code: 4060
// Cannot open database "%.*ls" requested by the login. The login failed.
case 4060 :
// SQL Error Code: 10928
// Resource ID: %d. The %s limit for the database is %d and has been reached.
case 10928:
// SQL Error Code: 10929
// Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d.
// However, the server is currently too busy to support requests greater than %d for this database.
case 10929:
// SQL Error Code: 10053
// A transport-level error has occurred when receiving results from the server.
// An established connection was aborted by the software in your host machine.
case 10053:
// SQL Error Code: 10054
// A transport-level error has occurred when sending the request to the server.
// (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
case 10054:
// SQL Error Code: 10060
// A network-related or instance-specific error occurred while establishing a connection to SQL Server.
// The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server
// is configured to allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed
// because the connected party did not properly respond after a period of time, or established connection failed
// because connected host has failed to respond.)"}
case 10060:
// SQL Error Code: 40197
// The service has encountered an error processing your request. Please try again.
case 40197:
// SQL Error Code: 40540
// The service has encountered an error processing your request. Please try again.
case 40540:
// SQL Error Code: 40613
// Database XXXX on server YYYY is not currently available. Please retry the connection later. If the problem persists, contact customer
// support, and provide them the session tracing ID of ZZZZZ.
case 40613:
// SQL Error Code: 40143
// The service has encountered an error processing your request. Please try again.
case 40143:
// SQL Error Code: 233
// The client was unable to establish a connection because of an error during connection initialization process before login.
// Possible causes include the following: the client tried to connect to an unsupported version of SQL Server; the server was too busy
// to accept new connections; or there was a resource limitation (insufficient memory or maximum allowed connections) on the server.
// (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
case 233:
// SQL Error Code: 64
// A connection was successfully established with the server, but then an error occurred during the login process.
// (provider: TCP Provider, error: 0 - The specified network name is no longer available.)
case 64:
// DBNETLIB Error Code: 20
// The instance of SQL Server you attempted to connect to does not support encryption.
case (int)ProcessNetLibErrorCode.EncryptionNotSupported:
return true;
}
}
}
else if (ex is TimeoutException)
{
return true;
}
else
{
EntityException entityException;
if ((entityException = ex as EntityException) != null)
{
return this.IsTransient(entityException.InnerException);
}
}
}
return false;
}
ADO。. NET SqlConnection类附带一个OpenWithRetry方法
例如:connection.OpenWithRetry(retryPolicy);
看看这个网站,我发现它非常有用,当我正在寻找一个重试策略的地方
http://geekswithblogs.net/ScottKlein/archive/2012/01/27/understanding-sql-azure-throttling-and-implementing-retry-logic.aspx