好的,为了将我的应用程序移动到云端,我已将本地SQL数据库移动到Azure SQL。问题是与新的Azure SQL数据库的连接是如此“好”,我将把它带回内部。
任务是循环并在数据库中创建总共约481K条记录。
连接字符串是
"Server=tcp:xxx,1433;Initial Catalog=xx;Persist Security Info=False;User ID=xx;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;ConnectRetryCount=255;"
每次运行的SQL查询并不复杂。只需将三个值插入三列即可。 (列和值已更改以保护某些内部工作)
Insert Into TheTable (C1, C2, C3) VALUES ('V1', 'V2', 'V3')
但随机点它会抛出这个。
System.ComponentModel.Win32Exception(0x80004005):等待操作超时执行超时已过期。操作完成之前经过的超时时间或服务器没有响应。 at System.Data.SqlClient.SqlConnection.OnError(SqlException exception,Boolean breakConnection,Action 1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 completion,String methodName,Boolean sendToPipe,Int32 timeout,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry)
在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
在D的D:\ PATHOFTHEFILE:第420行
请注意
1)每次创建记录并在下一步中关闭记录时,我都会打开和关闭连接。
2)除了我之外,没有其他人能够访问数据库。
3)数据库服务设置为S1。
4)是的 - 我有点讽刺的是程序在第420行崩溃了。我正试图找到方法来测试代码。
问题
1)我的连接字符串有什么问题吗?文档说我在连接到Azure SQL数据库时应该使用超时30。坦率地说,当我将超时设置为0时,代码运行得更好(或者至少寿命更长)。
2)首先,我尝试使用单个连接来处理整个481K INSERT语句的循环。这是一个糟糕的设计吗? Azure SQL可靠性有多长时间可以建立连接?
3)我对在Azure SQL上构建坚如磐石的应用程序的能力没有一种温暖的模糊感觉。有人能指出我对本地SQL与Azure SQL构建之间的区别的一个很好的参考。我已经找到了我能找到的所有东西,那里似乎没那么多。4)我喜欢可以使用MMC连接到Azure SQL的事实。但是(一般来说)我不能再从MMC获得各种监控信息了。任何人都有一个链接,可以帮助我真正了解数据库中发生的事情而不使用那个可怕的Azure门户
更新#1
罪名成立
public static void RunSQL(string SQLString)
{
int a = 0;
SqlCommand Command = new SqlCommand(SQLString, TheConnection);
try
{
a = Command.ExecuteNonQuery();
}
catch (Exception ex)
{
Notifications.EventLogging.ProcessEvent(SQLString + " go boom " + ex.InnerException + ex.Message + ex.StackTrace);
Notifications.EventLogging.ProcessEvent("Time Of Death" + DateTime.Now);
Console.ReadKey();
}
答案 0 :(得分:1)
Azure SQL实例托管在共享基础架构上。 Azure将限制请求以确保服务器上的所有实例都满足最低SLA。在这一生中,死亡和税收得到保证,但Azure SQL Connections却没有。
要解决此问题,您需要自动重试。多年来,Microsoft提供了一些选项,从现已弃用的ReliableSqlConnection类开始。目前与Azure SQL交流的首选方法是使用Entity Framework 6.x,它内置了自动重试功能。
实际上,看到轻量级和零星流量的Azure SQL数据库很少会看到限制事件。我有开发人员朋友,他们已经部署了生产代码到Azure SQL数据库,使用原始SqlConnections和SqlCommands,当我告诉他们无法保证连接时,他们似乎真的很惊讶。他们永远不会遇到它!但是,如果你正在从服务器中解决问题(正如你所做的那样),我已经看到它发生得足够明显。
编辑12-6-2018:我在过去几个月里遇到过这个问题。梳理完日志后,罪魁祸首是数据库流量激增,最大限度地提高了我的SQL Server的DTU限制。在这种情况下,重试不一定是一个充分的解决方案,因为自动重试有效地帮助阻塞SQL DB。要检查并查看您是否成为DTU限制的受害者,请转到Azure SQL DB的“概述”选项卡,查看资源利用率图表,并确保选择“最大值”作为度量标准。它默认为Avg,这可以隐藏DTU流量中的峰值。
答案 1 :(得分:1)
升级到高级版本的更高级别,进行迁移,然后相应地降级。这将帮助您解决超时错误。