簡體   English   中英

Azure - SqlBulkCopy 拋出超時過期異常

[英]Azure - SqlBulkCopy throwing a timeout expired exception

我在虛擬機上使用 azure sql 數據庫 (v12)。 我有兩個不同的數據庫實例 - 一個用於登台,一個用於生產。 我正在嘗試從暫存中獲取數據,然后單擊按鈕將其插入到生產中。 此代碼“有時”成功運行,這意味着它會隨機成功。 否則我會返回以下錯誤:

BULK COPY 提交異常類型:{0}System.Data.SqlClient.SqlException BULK COPY 消息:{0}超時已過期。 操作完成前超時時間已過或服務器未響應。 嘗試連接到路由目標時發生此故障。 嘗試連接到原始服務器所花費的時間為 - [Pre-Login] 初始化=1; 握手=17; 【登錄】初始化=0; 認證=0; 【登錄后】完成=0;

這是我用來完成此任務的代碼,也許存在我沒有看到的缺陷。 通過轉儲 StringBuilder,我可以看到 SELECT 查詢有效,DELETE 查詢有效,但是當我嘗試使用 SqlBulkCopy 復制數據時拋出錯誤。 任何幫助將不勝感激。 我已經瀏覽了一堆 MSDN 文檔,但沒有運氣-> 添加更長的 CommandTimeouts,添加更長的 BulkCopyTimeout,並在我的防火牆上重新配置端口。 仍然沒有運氣。

我使用過的資源: https : //social.msdn.microsoft.com/Forums/en-US/1467d64f-69ae-4c1f-91a2-349fc5d514ae/sqlbulkcopy-fails-with-timeout-expired-error?forum=adodotnetdataproviders

https://azure.microsoft.com/nb-no/documentation/articles/sql-database-develop-direct-route-ports-adonet-v12/

SqlBulkCopy 超時

public static object SyncData()
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("Internal Connection...");
    string internalConnectionString = GetConnectionString("ConnectionString");
    using (SqlConnection internalConnection = new SqlConnection(internalConnectionString))
    {
        internalConnection.Open();              
        SqlCommand selectCommand = internalConnection.CreateCommand();
        selectCommand.CommandTimeout = 180;
        try
        {
            selectCommand.CommandText = "SELECT * FROM dbo.test";
            SqlDataReader reader = selectCommand.ExecuteReader();

            sb.AppendLine("External Connection...");
            string externalConnectionString = GetConnectionString("ExternalConnectionString");
            using (SqlConnection externalConnection = new SqlConnection(externalConnectionString))
            {
                externalConnection.Open();              
                SqlCommand CRUDCommand = externalConnection.CreateCommand();
                CRUDCommand.CommandTimeout = 180;
                SqlTransaction transaction = externalConnection.BeginTransaction("test");
                CRUDCommand.Connection = externalConnection;
                CRUDCommand.Transaction = transaction;
                try
                {
                    CRUDCommand.CommandText = "DELETE FROM dbo.test";
                    sb.AppendLine("DELETE: Number of rows affected = " + CRUDCommand.ExecuteNonQuery());
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(externalConnection, SqlBulkCopyOptions.KeepIdentity, transaction))
                    {
                        try
                        {
                            bulkCopy.DestinationTableName = "dbo.test";
                            bulkCopy.BatchSize = 100;
                            bulkCopy.BulkCopyTimeout = 180;
                            bulkCopy.WriteToServer(reader);

                            sb.AppendLine("Table data copied successfully");

                            transaction.Commit();
                            sb.AppendLine("Transaction committed.");
                        }
                        catch (Exception ex)
                        {
                            sb.AppendLine("BULK COPY Commit Exception Type: {0}" + ex.GetType());
                            sb.AppendLine("  BULK COPY Message: {0}" + ex.Message);
                            try
                            {
                                transaction.Rollback();
                            }
                            catch (Exception ex2)
                            {
                                sb.AppendLine("Rollback Exception Type: {0}" + ex2.GetType());
                                sb.AppendLine("  Message: {0}" + ex2.Message);
                            }
                        }
                        finally
                        {
                            reader.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    sb.AppendLine("Commit Exception Type: {0}" + ex.GetType());
                    sb.AppendLine("  Message: {0}" + ex.Message);

                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception ex2)
                    {
                        sb.AppendLine("Rollback Exception Type: {0}" + ex2.GetType());
                        sb.AppendLine("  Message: {0}" + ex2.Message);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            sb.AppendLine("Commit Exception Type: {0}" + ex.GetType());
            sb.AppendLine("  Message: {0}" + ex.Message);
        }
    }
    return sb.ToString();
}

創建 SqlBulkCopy 實例時,您將傳遞連接字符串externalConnectionString並因此打開一個新連接。 這可能會導致兩個連接嘗試修改同一個表時出現死鎖問題。

您是否嘗試過將現有連接externalConnection傳遞給 SqlBulkCopy 構造函數而不是連接字符串?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM