ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL Azure连接丢失怎么办?

SQL Azure连接丢失怎么办?

原创 Linux操作系统 作者:shawnzhao98 时间:2010-06-24 11:40:19 0 删除 编辑
 

SQL Azure 连接丢失怎么办?

使用SQL Azure时,需要在互联网上建立连接,因此需要做好准备处理连接被异常删除,已建立的连接包括:返回数据的连接,打开连接池或客户端变量缓存中的连接。当你连接到SQL Azure时,连接是有可能丢失的,处理连接丢失最好的办法是重新建立连接,然后重新执行失败的命令或查询。

网络可靠性

运行你客户端代码的机器与SQL Azure服务器之间的所有网络组件的质量都在微软的控制范围之外,互联网上的任何原因都可能导致你的会话连接断开,在Windows Azure中运行应用程序时,连接丢失的风险会大大降低,因为应用程序和数据库之间的距离减少了,有可能它们都在同一个数据中心。

因网络问题致使会话连接断开时,SQL Azure不能给应用程序返回一个有意义的错误,因为会话已经终止了,但是,当重新使用这个连接时,你将获得一个10053错误。

连接重试

如果你在本地局域网内连接到单个SQL Server服务器,当它失效或进行例行停机维护时,你的应用程序将永久断开,但如果你不止一台SQL Server服务器,并且应用程序代码做了修改,当主服务器不可用时,应用程序就自动连接到备用服务器,这时只需很短暂的断开时间,SQL Azure的行为和一个具有冗余功能的SQL Server集群类似,SQL Azure Fabric管理系统中每个节点的健康状态,它要么通知节点的状态不健康,要么是节点已准备好脱机,Fabric将会自动将你的会话重新连接到另一个节点的副本数据库上。

目前有些故障转移行为会导致会话意外终止,而客户端会接收到一个普通的网络断开错误,这种情况下最好的做法是重新连接,SQL Azure会自动将你连接到一个健康的数据库。

SQL Azure资源管理

与其它数据库类似,SQL Azure会在遇到错误,资源短缺和其它原因时会终止会话,在这些情况下,如果客户端连接有活动请求,SQL Azure总是尝试返回一个特定的错误,需要注意的是,如果没有挂起的请求,不是每次都能成功向客户端应用程序返回一个错误。例如,如果你通过 SQL Server Management Studio 连接数据库的时间超过了30分钟无活动请求,你的会话将会超时,因为无活动请求,SQL Azure就不能返回一个错误。

在以下这些情况下,SQL Azure将会关闭一个已建立的连接:

·  应用程序持有空闲连接的时间超过了30分钟;

·  你去吃午餐,但你的 SQL Server Management Studio 连接超过了30分钟无活动。

SQL Azure错误

除了前面提到的10053错误,还有两个错误代码比较有用:

·  40197:服务处理你的请求时遇到错误,请重试。

·  40501:服务繁忙,请10秒后重试。

处理连接丢失的代码

下面的代码考虑到了互联网的延迟和连接被删除的可能:

·  重新执行失败的命令或查询,时间配置在.config文件中;

·  每次尝试连接的等待时间也配置在.config文件中;

·  只处理应该重新尝试的异常,抛出另外的异常;

·  提取异常屏幕,便于将来增加其他情景。

C#代码:

/// 

/// Generic Code that takes and input and executes 

/// a statement against the SQL Azure

/// 

/// 

static void DoSomething(Int32 companyId)

{

    // This is the retry loop, handling the retries session

    // is done in the catch for performance reasons

    for (Int32 attempt = 1; ; )

    {

        // Create a SqlConnection Class, the connection isn't established 

        // until the Open() method is called

        using (SqlConnection sqlConnection = new SqlConnection(

            ConfigurationManager.ConnectionStrings["SQLAzure"].

                ConnectionString))

        {

            try

            {

                // Open the connection

                sqlConnection.Open();

                // Statement To Call

                String sql = @"SELECT Color FROM Source WHERE Id = @CompanyId";

                SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);

                sqlCommand.Parameters.AddWithValue("@CompanyId", companyId);

                using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())

                {

                    while (sqlDataReader.Read())

                    {

                        /// Do Something Wtih Color

                    }

                    return;

                }

            }

            catch (SqlException sqlException)

            {

                // Increment Trys

                attempt++;

                // Find Maximum Trys

                Int32 maxRetryCount = Int32.Parse(

                    ConfigurationManager.AppSettings["ConnectionRetrys"]);

                // Throw Error if we have reach the maximum number of retries

                if (attempt == maxRetryCount)

                    throw;

                // Determine if we should retry or abort.

                if (!RetryLitmus(sqlException))

                    throw;

                else

                    Thread.Sleep(ConnectionRetryWaitSeconds(attempt));

            }

        }

    }

}

static Int32 ConnectionRetryWaitSeconds(Int32 attempt)

{

    Int32 connectionRetryWaitSeconds = Int32.Parse(ConfigurationManager.

        AppSettings["ConnectionRetryWaitSeconds"])

        * 1000;

    // Backoff Throttling

    connectionRetryWaitSeconds = connectionRetryWaitSeconds *

        (Int32)Math.Pow(2, attempt);

    return (connectionRetryWaitSeconds);

}

/// 

/// Determine from the exception if the execution

/// of the connection should Be attempted again

/// 

/// Generic Exception

/// True if a a retry is needed, false if not

static Boolean RetryLitmus(SqlException sqlException)

{

    switch (sqlException.Number)

    {

        // The service has encountered an error

        // processing your request. Please try again.

        // Error code %d.

        case 40197:

        // The service is currently busy. Retry

        // the request after 10 seconds. Code: %d.

        case 40501:

        //A transport-level error has occurred when

        // receiving results from the server. (provider:

        // TCP Provider, error: 0 - An established connection

        // was aborted by the software in your host machine.)

        case 10053:

            return (true);

    }

    return (false);

}

.config文件

  

    

Database=Test;User ID=login@server;Password=yourPassword;

Trusted_Connection=False;Encrypt=True;"/>

  

  

    

    

  

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9915007/viewspace-666068/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2010-06-24

  • 博文量
    2
  • 访问量
    3898