zoukankan      html  css  js  c++  java
  • 数据访问超时问题的总结

    我们经常会讨论到数据访问超时的问题,当数据库服务器在远程,而且该操作需要耗用较长的时间的时侯,程序经常性出现一些超时的问题。那么应该从几个层面来探讨这个问题呢

    1. 首先,我们来了解一下SQL Server内部执行的时间(默认是无限期等待的,即无超时)

    image

    2.其次,我们要知道SqlConnection的ConnectionTimeout属性,默认为15秒。这是获取在尝试建立连接时终止尝试并生成错误之前所等待的时间

    该值不能通过编程设置,而是直接在连接字符串中指定

    3.比较关键的是,我们要知道SqlCommand的CommandTimeout属性,默认为30秒。获取或设置在终止执行命令的尝试并生成错误之前的等待时间

    值 0 指示无限制,在 CommandTimeout 中应避免值 0,否则会无限期地等待执行命令

    此属性是在执行命令或处理结果期间所有网络读取的累积超时。在返回第一行之后,超时仍然可能发生,但只包括网络读取时间,而不包括用户处理时间。

    结合这三点,我做了一个例子。下面的存储过程是故意地阻塞2分钟。

    CREATE PROC GetServerTime(@result DATETIME OUTPUT)
    AS
    WAITFOR DELAY '00:02:00'
    SET @result=getdate()

    下面是客户端代码

    using System;
    using System.Data.SqlClient;
    using System.Data;

    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                SqlConnection conn = null;
                try
                {
                    using (conn = new SqlConnection("server=(local);database=northwind;integrated security=true;connection timeout=30"))
                    {
                        //Console.WriteLine(conn.ConnectionTimeout.ToString());
                        conn.Open();
                        using (SqlCommand cmd = conn.CreateCommand())
                        {
                            cmd.CommandTimeout = 0;//这里设置为0,即取消了命令的超时限制
                            cmd.CommandText = "GetServerTime";
                            cmd.CommandType = CommandType.StoredProcedure;
                            SqlParameter param = new SqlParameter("@result", SqlDbType.DateTime);
                            param.Direction = ParameterDirection.Output;
                            cmd.Parameters.Add(param);
                            Console.WriteLine("开始工作:" + DateTime.Now.ToString());
                            cmd.ExecuteNonQuery();
                            Console.WriteLine("取得结果:"+param.Value.ToString());
                        }
                        conn.Close();

                    }
                }
                catch (SqlException ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    if (conn != null && conn.State != ConnectionState.Closed)
                        conn.Close();
                }

                Console.Read();
            }
        }
    }

    4.当该代码放在中间层,我们这里用Web Service为例,看看是否有什么问题?

    using System.ComponentModel;
    using System.Data;
    using System.Web.Services;
    using System.Data.SqlClient;

    namespace WebService1
    {
        /// <summary>
        /// Service1 的摘要说明
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [ToolboxItem(false)]
        public class Service1 : System.Web.Services.WebService
        {

            [WebMethod]
            public string GetServerTime()
            {
                SqlConnection conn = null;
                string result = string.Empty;
                try
                {
                    using (conn = new SqlConnection("server=(local);database=northwind;integrated security=true;connection timeout=30"))
                    {
                        //Console.WriteLine(conn.ConnectionTimeout.ToString());

                        conn.Open();
                        using (SqlCommand cmd = conn.CreateCommand())
                        {
                            cmd.CommandTimeout = 0;
                            cmd.CommandText = "GetServerTime";
                            cmd.CommandType = CommandType.StoredProcedure;
                            SqlParameter param = new SqlParameter("@result", SqlDbType.DateTime);
                            param.Direction = ParameterDirection.Output;
                            cmd.Parameters.Add(param);
                            cmd.ExecuteNonQuery();
                            result= param.Value.ToString();
                        }
                        conn.Close();

                    }
                }
                catch (SqlException ex)
                {
                    throw ex;
                }
                finally
                {
                    if (conn != null && conn.State != ConnectionState.Closed)
                        conn.Close();
                }

                return result;
            }
        }
    }

    我们用客户端调用该web server,但仍然会超时。同样的代码,为什么会产生不一样的结果呢?

    还要注意的一个地方是调用web service的客户端代理的超时设置。准确地说,大部分web service的代理类都是继承自WebClientProtocol类的。这个类有一个属性:timeout

    http://msdn.microsoft.com/zh-cn/library/system.web.services.protocols.webclientprotocol.timeout.aspx

    指示 XML Web services 客户端等待同步 XML Web services 请求完成的时间(以毫秒计)。默认值为 100000 毫秒。(即100秒)

    如果将 Timeout 属性设置为 Timeout..::.Infinite,则指示该请求无超时。即使 XML Web services 客户端可以将 Timeout 属性设置为无超时,Web 服务器仍可以在服务器端使请求超时

     

    ASP.NET的程序默认的执行超时时间为110秒,这是通过web.config文件中的一个属性设置的。就是下面这个executionTimeout.单位为秒,默认为110.以前是90.

    image

    image

    注意,该属性只有当debug=false才生效

  • 相关阅读:
    PostgreSQL查看等待锁的SQL和进程
    effective_io_concurrency很重要的一个参数
    PostgreSQL逻辑复制到kafka-实践
    Linux下路由配置梳理(转)
    创建B树,动态添加节点,并使用三种遍历算法对树进行遍历
    思考--PostgreSQL在与mysql的比较中稍微弱势项
    思考-继续思考在数据库中两个表join的问题
    思考--mysql 分库分表的思考
    超级实用的网址大全
    C++ 读取txt文本内容,并将结果保存到新文本
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1266086.html
Copyright © 2011-2022 走看看