C# 正确处理数据库连接问题的方法
我在尝试连接数据库时遇到以下错误: 运行时发生与网络相关或特定于实例的错误 正在建立与SQL Server的连接。找不到服务器,或者 无法访问。验证实例名称是否正确,以及 SQL Server配置为允许远程连接。(提供者:已命名) 管道提供程序,错误:40-无法打开到SQL Server的连接) 现在,有时我会遇到这个错误,有时我不会,例如:当我第一次运行程序时,它成功地打开了连接,当我第二次运行时,我会遇到这个错误,下一次再次运行程序时,我不会遇到错误 当我尝试通过SSMS连接到同一个数据库服务器时,我能够成功连接,但我的程序中只出现了这个网络问题 数据库不在myLOCAL中。它位于AZURE上 我的本地数据库没有出现此错误 代码:C# 正确处理数据库连接问题的方法,c#,ado.net,azure-sql-database,sqlconnection,C#,Ado.net,Azure Sql Database,Sqlconnection,我在尝试连接数据库时遇到以下错误: 运行时发生与网络相关或特定于实例的错误 正在建立与SQL Server的连接。找不到服务器,或者 无法访问。验证实例名称是否正确,以及 SQL Server配置为允许远程连接。(提供者:已命名) 管道提供程序,错误:40-无法打开到SQL Server的连接) 现在,有时我会遇到这个错误,有时我不会,例如:当我第一次运行程序时,它成功地打开了连接,当我第二次运行时,我会遇到这个错误,下一次再次运行程序时,我不会遇到错误 当我尝试通过SSMS连接到同一个数据库服
public class AddOperation
{
public void Start()
{
using (var processor = new MyProcessor())
{
for (int i = 0; i < 2; i++)
{
if(i==0)
{
var connection = new SqlConnection("Connection string 1");
processor.Process(connection);
}
else
{
var connection = new SqlConnection("Connection string 2");
processor.Process(connection);
}
}
}
}
}
public class MyProcessor : IDisposable
{
public void Process(DbConnection cn)
{
using (var cmd = cn.CreateCommand())
{
cmd.CommandText = "query";
cmd.CommandTimeout = 1800;
cn.Open();//Sometimes work sometimes dont
using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
//code
}
}
}
}
我对以上两个选项感到困惑
有谁能告诉我解决此问题的更好方法吗?正如您所知,即使是安装在Azure VM(IaaS)上的SQL Server,也建议使用重试逻辑
故障处理:应用程序代码包括重试逻辑和
瞬时故障处理?包括正确的重试逻辑和瞬态
代码中的故障处理补救应该是一种通用的最佳方法
在本地和云中实践,IaaS或PaaS。如果
如果缺少此特性,则可能会在这两个方面出现应用程序问题
Azure VM中的Azure SQLDB和SQL Server,但在此场景中
与前者相比,建议采用后者
建议使用增量重试逻辑
有两种基本方法可以实例化应用程序所需的应用程序块中的对象。在第一种方法中,可以显式实例化代码中的所有对象,如以下代码段所示:
var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2));
var retryPolicy =
new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(retryStrategy);
// Load policies from the configuration file.
// SystemConfigurationSource is defined in
// Microsoft.Practices.EnterpriseLibrary.Common.
using (var config = new SystemConfigurationSource())
{
var settings = RetryPolicyConfigurationSettings.GetRetryPolicySettings(config);
// Initialize the RetryPolicyFactory with a RetryManager built from the
// settings in the configuration file.
RetryPolicyFactory.SetRetryManager(settings.BuildRetryManager());
var retryPolicy = RetryPolicyFactory.GetRetryPolicy
<SqlDatabaseTransientErrorDetectionStrategy>("Incremental Retry Strategy");
...
// Use the policy to handle the retries of an operation.
}
var retryStrategy=new Incremental(5,TimeSpan.FromSeconds(1),
时间跨度从秒(2)开始;
风险回报政策=
新RetryPolicy(retryStrategy);
在第二种方法中,您可以根据配置数据实例化和配置对象,如以下代码段所示:
var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2));
var retryPolicy =
new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(retryStrategy);
// Load policies from the configuration file.
// SystemConfigurationSource is defined in
// Microsoft.Practices.EnterpriseLibrary.Common.
using (var config = new SystemConfigurationSource())
{
var settings = RetryPolicyConfigurationSettings.GetRetryPolicySettings(config);
// Initialize the RetryPolicyFactory with a RetryManager built from the
// settings in the configuration file.
RetryPolicyFactory.SetRetryManager(settings.BuildRetryManager());
var retryPolicy = RetryPolicyFactory.GetRetryPolicy
<SqlDatabaseTransientErrorDetectionStrategy>("Incremental Retry Strategy");
...
// Use the policy to handle the retries of an operation.
}
//从配置文件加载策略。
//SystemConfigurationSource在中定义
//Microsoft.Practices.EnterpriseLibrary.Common。
使用(var config=new SystemConfigurationSource())
{
var settings=RetryPolicyConfigurationSettings.GetRetryPolicySettings(配置);
//使用从中生成的RetryManager初始化RetryPolicyFactory
//配置文件中的设置。
RetryPolicyFactory.SetRetryManager(settings.BuildRetryManager());
var retryPolicy=RetryPolicyFactory.GetRetryPolicy
(“增量重试策略”);
...
//使用策略处理操作的重试。
}
有关详细信息,请访问文档。使用新版本的.NET(4.6.1或更高版本),然后利用内置的恢复功能:
ConnectRetryCount、ConnectRetryInterval和连接超时
有关更多信息,请参阅:您使用的是SQL Express还是工作组版?如果是这样,可能是服务器太忙而无法响应 要排除网络问题,请在命令提示符下执行
PING-tsqlservername
。是每一个ping都回来了,还是有些丢失了?这可能是网络中断的指示器,也可能导致此错误,如故障交换机。如果它们都丢失了(考虑到您的数据库连接有时可以正常工作),那么ping很可能被某个地方的防火墙阻止了:如果您找到该阻止并临时取消阻止,这可能有助于诊断
错误消息表明您正在使用命名管道。您是否有意使用命名管道?对于大多数场景(包括Azure数据库),我建议在SQL Server Configuration Manager中启用TCP/IP并禁用命名管道
根据Azure数据库的“距离”,路由器和防火墙造成的延迟有时会打乱Kerberos和/或相关计时。您可以通过使用连接字符串中的端口来克服这一问题,以避免往返到端口1434来枚举实例。我假设您已经在使用FQDN。例如:服务器\例如,端口连接完全可能断开。“分布式计算的谬误”:。 这可能是网络连接问题。可能在任何一端 我建议:(假设在Azure上为您的计算机启用了防火墙)
如前所述,它现在是框架的一部分,您可以使用它,或者您创建的框架应该可以使用。理想情况下,拥有重试逻辑是很好的,即使您对连接性和速度很确定。以防万一:)所有与远程服务通信的应用程序都对瞬时故障敏感 如其他答案中所述,如果客户端程序使用.NET Framework类System.Data.SqlClient.SqlConnection连接到SQL数据库,请使用.NET 4.6.1或更高版本(或.NET Core),以便使用其连接重试功能 为SqlConnection对象生成连接字符串时,请协调以下参数之间的值: ConnectRetryCount:默认值为1。范围是0到255
RetryPolicy retryPolicy = Policy.Handle<Exception>()
.WaitAndRetry(3, retryAttempt =>
TimeSpan.FromSeconds(retryAttempt));
var result = retryPolicy.Execute(() => someClass.DoSomething());