C# ADO - timeout 引出的探讨

来源:互联网 发布:名片设计软件手机版 编辑:程序博客网 时间:2024/06/14 04:01

最近做一个项目,在数据库库操作中遇到如下问题:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 

我是使用C#通过ADO调用一个存储过程去获得数据,因为该存储过程要执行较长时间,所以超时了。解决办法就是设定 SqlCommand 对象的CommandTimeout属性大一些比如360秒。这个需要自己调整。

下面对 Timeout 进行下总结吧。

1. ADO 连接数据库时,在连接串中有个参数 Timeout ,如果不设置就是15秒。这个是控制连接打开的时间的,是指你是否能在指定时间内(单位是秒)连上数据库。

Server=127.0.0.1 or domain name; Database=myDataBase_instance;User Id=myUsername; Password=myPassword;Timeout=15;

我没有列出其他无关此主题的项目为了避免干扰视听。

2. SqlCommand 中有个CommandTimeout属性, 这个是为了你执行 命令(比如 增删改查) 的时间限定(单位是秒)。

cmd.CommandTimeout = Your commandTimeout; // Note: cmd 是 SqlCommand 对象

Note: 设置太大了也会占用资源,一般2-3 分钟应该够用了,否则该看看你的存储过程是否有设计问题了。

3. 给出一小段代码吧,是从我的程序中摘出来的,没测试哈。

你的函数中可以使用:

函数名加函数签名( 自己想, 自己想 有的参数是不是可以传引用呢,自己想。。)

{

if (conn.State != ConnectionState.Open) // 尽可能复用已经建立的连接
conn.Open();
 
//构造你的SqlCommand 对象
cmd.Connection = conn;
cmd.CommandText = cmdText;       
cmd.CommandType = cmdType;
cmd.CommandTimeout = Your commandTimeout;  //
这个是相关于该主题 哈哈


if (trans != null)    // 如果你使用 SqlTransaction 对象,用之 
cmd.Transaction = trans;


if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
{
if(parm.SqlValue == null) {parm.SqlValue = DBNull.Value; }
cmd.Parameters.Add(parm);
}
}
  

}


对超时的问题我们可以看到两点,一个是在连接层面,一个是在执行层面。连接层面涉及到数据库连接池的问题。但我们更多的是关注在执行层面。不论如何,要考虑自己的项目的实际需求而定:是否是时间敏感的,是否是优先级高的,是否是仅仅需要查询的(若是,是否考虑过在存储过程中使用 with no lock 等机制 - 要考虑数据一致性的要求等),是否你的程序可以阻塞,是否你的程序是多线程的,是否你的命令对象是是事务型的。这些是一个整体而不是仅仅这样一个剖面。但不积跬步,无以至千里,就象我这第一篇技术博客一样,会有绽放的一天。



0 0
原创粉丝点击