该篇文章是我于2009年6月10日通过自己编写的工具,批量从位于在博客园的博客站点(http://chenxizhang.cnblogs.com)同步而来。文章中的图片地址仍然是链接到博客园的。特此说明!
陈希章 原文地址:http://www.cnblogs.com/chenxizhang/archive/2008/08/12/1266086.html 原文标题:数据访问超时问题的总结 原文发表:2008/8/12 7:56:00
|
我们经常会讨论到数据访问超时的问题,当数据库服务器在远程,而且该操作需要耗用较长的时间的时侯,程序经常性出现一些超时的问题。那么应该从几个层面来探讨这个问题呢
1. 首先,我们来了解一下SQL Server内部执行的时间(默认是无限期等待的,即无超时)

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
{
??? ///
??? /// Service1 的摘要说明
??? /// ??? [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.


注意,该属性只有当debug=false才生效
作者:陈希章 出处:http://blog.csdn.net/chen_xizhang 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 |