关于.NET中数据库连接超时的管理
不知道大家在访问数据库,特别是远程数据库的时候有没有碰到这么一种情况。如果远程计算机没有打开,或者网络中断。这时不管你数据库连接设置的是多少秒,都会等待30-60秒左右的时间。这段时间其实是在等待不存在的主机的响应。
       在C#中,其实我们完全可以控制这段时间,避免长时间的等待。因为这样对于一些系统,比如把数据库访问放在一个队列里面查询的系统来说,这样造成的时间浪费不可估计。因为正常情况下,打开数据库连接的时间很短。
       于是,我封装了一个类,通过多线程的方式,来控制这段时间。如果在指定时间,如5秒,没有连接上,则中断连接。并做出相应处理。这样,节约了很多的时间。
       在这里,我们首先简单介绍一下多线程。
       大家都知道,一个进程下面包含,多个线程。线程还分为主线程和后台线程。主线程中断后,后台线程会同时中断,反之,后台线程中断不会影响主线程。多线程编程中,如果没有把线程设置为后台线程,还不能用Abort()方法来中断线程。
       我封装了一个叫DbConnConsole的类。用来管理数据库连接超时,并支持多种数据库。
具体代码如下:
 
 using System;
using System;2
 using System.Threading;
using System.Threading;3
 using System.Data;
using System.Data;4
 using System.Data.SqlClient;
using System.Data.SqlClient;5
 using Microsoft.Data.Odbc;
using Microsoft.Data.Odbc;6
 using System.Data.OleDb;
using System.Data.OleDb;7

8

9
 namespace DBConnConsole
namespace DBConnConsole10
 {
{11

12
 /// <summary>
    /// <summary>13
 /// 数据库类型
    /// 数据库类型14
 /// </summary>
    /// </summary>15
 public enum DatabaseType
    public enum DatabaseType16
 {
    {17
 SqlServer,
        SqlServer,           18
 Odbc,
        Odbc,19
 Oracle,
        Oracle,20
 OleDB
        OleDB21
 }
    }22

23

24

25

26
 /// <summary>
    /// <summary>27
 /// 通过线程控制数据库连接时间管理
    /// 通过线程控制数据库连接时间管理28
 /// </summary>
    /// </summary>29
 public class DbConnConsole
    public class DbConnConsole30
 {
    {31
 private bool bIsConn = false;                    // 判断连接是否成功
        private bool bIsConn = false;                    // 判断连接是否成功32
 private Thread tdConn;                            // 连接数据库的线程
        private Thread tdConn;                            // 连接数据库的线程33
 private string strConn = null;                    // 连接字符串
        private string strConn = null;                    // 连接字符串34
 private int nTimeout = 0;                        // 超时时间
        private int nTimeout = 0;                        // 超时时间35
 private DatabaseType dbType;                    // 数据库类型
        private DatabaseType dbType;                    // 数据库类型36
 private IDbConnection iConn = null;     // 数据库连接字符串对象接口
        private IDbConnection iConn = null;     // 数据库连接字符串对象接口 37
 
        38

39
 /// <summary>
        /// <summary>40
 /// 构造函数
        /// 构造函数41
 /// </summary>
        /// </summary>42
 /// <param name="Conn">连接字符串</param>
        /// <param name="Conn">连接字符串</param>43
 /// <param name="timeOut">超时时间(毫秒)</param>
        /// <param name="timeOut">超时时间(毫秒)</param>44
 /// <param name="DBType">数据库类型</param>
        /// <param name="DBType">数据库类型</param>45
 public DbConnConsole(string Conn, int timeOut, DatabaseType DBType)
        public DbConnConsole(string Conn, int timeOut, DatabaseType DBType)46
 {
        {47
 strConn = Conn;
            strConn = Conn;48
 nTimeout = timeOut;
            nTimeout = timeOut;49
 dbType = DBType;
            dbType = DBType;50
 }
        }51

52

53
 /// <summary>
        /// <summary>54
 /// 打开数据库
        /// 打开数据库55
 /// </summary>
        /// </summary>56
 /// <returns>连接对象接口</returns>
        /// <returns>连接对象接口</returns>57
 public IDbConnection Open()
        public IDbConnection Open()58
 {
        {59
 tdConn = new Thread(new ThreadStart(ConnDatabase));
            tdConn = new Thread(new ThreadStart(ConnDatabase));60
 Thread tdTimeOut = new Thread(new ThreadStart(ConsoleTimeOut));
            Thread tdTimeOut = new Thread(new ThreadStart(ConsoleTimeOut));61
 tdConn.ApartmentState = ApartmentState.MTA;
            tdConn.ApartmentState = ApartmentState.MTA;62
 tdConn.IsBackground = true;
            tdConn.IsBackground = true;63
 tdTimeOut.Start();
            tdTimeOut.Start();64
 tdTimeOut.Priority = ThreadPriority.Highest;
            tdTimeOut.Priority = ThreadPriority.Highest;65
 tdConn.Start();
            tdConn.Start();66
 
            67
 tdTimeOut.Join();             //连接超时控制线程,不然主线程会直接返回null.  !!!!
            tdTimeOut.Join();             //连接超时控制线程,不然主线程会直接返回null.  !!!!68
 return iConn;
            return iConn;69
 }
        }70

71

72

73
 /// <summary>
        /// <summary>74
 /// 超时控制
        /// 超时控制75
 /// </summary>
        /// </summary>76
 private void ConsoleTimeOut()
        private void ConsoleTimeOut()77
 {
        {78
 Thread.Sleep(nTimeout);
            Thread.Sleep(nTimeout);79
 if (bIsConn == false)
            if (bIsConn == false)80
 {
            {81
 tdConn.Abort();
                tdConn.Abort();82
 tdConn = null;
                tdConn = null;83
 iConn = null;
                iConn = null;84
 }
            }85
 }
        }86

87

88
 /// <summary>
        /// <summary>89
 /// 连接数据库
        /// 连接数据库90
 /// </summary>
        /// </summary>91
 private void ConnDatabase()
        private void ConnDatabase()92
 {
        {93
 try
            try94
 {
            {95
 
            96
 //根据数据连接类型创建数据访问类
                //根据数据连接类型创建数据访问类97
 switch (dbType)
                switch (dbType)98
 {
                {99
 case DatabaseType.SqlServer:
                    case DatabaseType.SqlServer:100
 iConn = new SqlConnection(strConn);
                        iConn = new SqlConnection(strConn);101
 iConn.Open();
                        iConn.Open();102
 break;
                        break;103
 case DatabaseType.Odbc:
                    case DatabaseType.Odbc:104
 iConn = new OdbcConnection(strConn);
                        iConn = new OdbcConnection(strConn);105
 iConn.Open();
                        iConn.Open();106
 break;
                        break;107
 case DatabaseType.OleDB:
                    case DatabaseType.OleDB:108
 iConn = new OleDbConnection(strConn);
                        iConn = new OleDbConnection(strConn);109
 iConn.Open();
                        iConn.Open();110
 break;
                        break;111
 }
                }            112
 
            113
 bIsConn = true;
                bIsConn = true;114
 }
            }115
 catch (Exception exp)
            catch (Exception exp)116
 {
            {117
 System.Diagnostics.Debug.WriteLine(exp.ToString());
                System.Diagnostics.Debug.WriteLine(exp.ToString());118
 }
            }119
 
            120
 }
        }121
 }
    }122
 }
}123

124
 现在访问数据库则为:
       现在访问数据库则为:125
 string strConn = "data source=192.168.1.253;initial catalog=Northwind;"
    string strConn = "data source=192.168.1.253;initial catalog=Northwind;"126
 + "user id=sa;pwd=098697;packet size=4096;Connect Timeout=10";
    + "user id=sa;pwd=098697;packet size=4096;Connect Timeout=10";127

128
 DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);
     DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);129
 IDbConnection iConn = null;
     IDbConnection iConn = null;130

131

132
 iConn = dbConsole.Open();
    iConn = dbConsole.Open();133
 
    134
 if (iConn != null)
    if (iConn != null)135
 {
    {136
 
            137
 string strQuery = "select * from Employees";
        string strQuery = "select * from Employees";138
 SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);
        SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);139
 DataSet ds = new DataSet();
        DataSet ds = new DataSet();140
 sqlDA.Fill(ds);
        sqlDA.Fill(ds);141

142
 dgTest.DataSource = ds.Tables[0].DefaultView;
        dgTest.DataSource = ds.Tables[0].DefaultView;143
 }
    }144
 else
    else145
 {
    {146
 MessageBox.Show("失败!");
        MessageBox.Show("失败!");147
 }
    }最终,我们返回了一个数据库连接接口。
下面,我给出测试代码,以便测试程序正确性。
  string strConn = "data source=192.168.1.253;initial catalog=Northwind;"
    + "user id=sa;packet size=4096;Connect Timeout=10";
     
//其中的3000为控制的超时时间
     DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);
     IDbConnection iConn = null;
    iConn = dbConsole.Open();
    
    if (iConn != null)
    {
            
        string strQuery = "select * from Employees";
        SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);
        DataSet ds = new DataSet();
        sqlDA.Fill(ds);
        dgTest.DataSource = ds.Tables[0].DefaultView;
    }
    else
    {
        MessageBox.Show("失败!");
    }
   
这样,我们通过这个类,可以在任何数据库系统下面,实现连接超时管理,使系统功能更加的完善。
该代码在.net framework1.0 和 .net framework1.1下面均测试通过。
并在win2000,win2003,winxp下面均测试通过。
我的邮箱是 tony111082@hotmail.com
如果有什么问题,大家可以发邮件给我。
当然,也可以通过QQ:17490957.
 
                    
                     
                    
                 
                    
                

 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号 
