Azure SQL 连接超时

TRH*_*TRH 4 sql-server odbc azure

好的,为了将我的应用程序移至云端,我已将本地 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;"
Run Code Online (Sandbox Code Playgroud)

它每次运行的 SQL 查询并不复杂。只需将三个值插入三列。(列和值已更改以保护一些内部工作)

Insert Into TheTable (C1, C2, C3) VALUES ('V1', 'V2', 'V3')
Run Code Online (Sandbox Code Playgroud)

但在随机点它抛出这个。

System.ComponentModel.Win32Exception (0x80004005): 等待操作超时执行超时过期。操作完成前超时时间已过或服务器未响应。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,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(TaskCompletionSource1 完成,String methodName,Boolean sendToPipe,Int32 超时,Boolean&usedCache,Boolean asyncWrite,Boolean inRetry) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery( ) 在 D:\PATHOFTHEFILE:line 420 中的 XX

注意

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();

            }
Run Code Online (Sandbox Code Playgroud)

Rob*_*gan 9

Azure SQL 实例托管在共享基础结构上。Azure 将限制请求以确保服务器上的所有实例都能满足最低 SLA。在此生,死亡和税收是有保障的,但 Azure SQL 连接不是。

为了解决这个问题,你需要自动重试。多年来,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 流量中的峰值。

2019 年 6 月 8 日编辑:如果 DTU达到最大值并想知道是什么原因造成的,可以在 Azure 门户中的 Azure SQL 管理边栏选项卡上查看几个位置:

  1. 查询性能洞察。您可以使用此处的工具查找在给定时间段内运行的最消耗资源的查询。这是一个很好的起点。确保检查所有指标。
  2. 性能建议。如果您缺少索引,它可能已在此处列出。
  3. 指标。检查所有列出的。确保将聚合设置为 Max。

这应该为您提供良好(甚至很好)的错误指标。


Ger*_*kuş 5

升级到更高级别的高级版本,迁移然后相应降级。这将帮助您解决超时错误。

  • 如果您这样做,请务必设置提醒以避免意外费用。人们很容易忘记切换回来,而且费用可能会非常昂贵。如果你在家工作,我建议你把床上的枕头拿掉——这样你就无法入睡而不记得降级:-)或者只是脱下一只鞋子,把它扔到房间的另一边。 (2认同)