2017-02-22 62 views
0

好吧,爲了將我的應用程序移到雲端,我將本地SQL數據庫移到了Azure SQL中。問題是,與新的Azure SQL數據庫的連接是如此'flakey',我即將把它帶回家。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):等待操作超時超時超時。操作完成之前超時的時間或服務器沒有響應。在System.Data.SqlClient.SqlConnection.OnError(SqlException異常,布爾breakConnection,動作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次完成,字符串方法名,布爾sendToPipe,的Int32超時,布爾& usedCache,布爾asyncWrite,布爾inRetry) 在System.Data.SqlClient.SqlCommand .ExecuteNonQuery() 在XX中d:\ PATHOFTHEFILE:線420

注意

1)我打開和每個I創建記錄時間關閉連接並在下一步驟關閉它。

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

您是否使用SqlConnections和SqlCommands連接到數據庫?如果是這樣,我相信我確切地知道你的問題是什麼。 –

+0

有罪負責 - 請參閱我上面的實際代碼在更新#1 – TRH

回答

0

Azure的SQL實例託管在共享基礎架構上Azure會限制請求以確保服務器上的所有實例都能達到最低SLA。在這一生中,死亡和稅收都是有保證的,但Azure SQL連接不是。

要解決這個問題,您需要自動重試。多年來,微軟提供了幾個選項,從現在已棄用的ReliableSqlConnection類開始。目前與Azure SQL交談的首選方式是使用實體框架6.x,該框架內置了自動重試功能。

實際上,看到光線和偶發流量的Azure SQL數據庫很少會看到一個節流事件。我曾經有過部署生產代碼的開發者朋友使用了原始的SqlConnections和SqlCommands,並且當我告訴他們連接不能保證時,似乎真的很驚訝。他們從未穿過它!但是如果你從服務器上下了地獄(正如你所做的那樣),我發現它足以引起人們的注意。

切換到EF6,這將被照顧。

+0

好的,我明白了。 但是我正在看DTU的這個服務器實例(S1),它似乎沒有超過可用DTU的20%-30%。我認爲在Azure開始查殺連接之前,DTU必須達到100%。我的意思是,畢竟,我們有不同的DTU級別來適應不同級別的服務器衝擊 - 對嗎? 作爲一個短期修復,我會嘗試一個Thread.Sleep之間的迭代,看看是否減輕負載。 但我會嘗試EF轉換作爲我的週末項目。 – TRH

+0

請記住,「DTU」是由Microsoft未提供的其他幾個度量標準組成的度量標準。僅僅因爲DTU不被釘住並不意味着你沒有被限制。這是一個涉及EF的能力和使用Azure SQL時需要的頁面:https://msdn.microsoft.com/en-us/library/dn456835(v=vs.113).aspx –

+0

是的,那是我的恐懼 - 我盯着組成DTU的未定義參數之一,而沒有在整個DTU範圍內出現它。我會讓你的鏈接在本週末閱讀。 – TRH