关于.NET中数据库连接超时的管理
不知道大家在访问数据库,特别是远程数据库的时候有没有碰到这么一种情况。如果远程计算机没有打开,或者网络中断。这时不管你数据库连接设置的是多少秒,都会等待30-60秒左右的时间。这段时间其实是在等待不存在的主机的响应。
在C#中,其实我们完全可以控制这段时间,避免长时间的等待。因为这样对于一些系统,比如把数据库访问放在一个队列里面查询的系统来说,这样造成的时间浪费不可估计。因为正常情况下,打开数据库连接的时间很短。
于是,我封装了一个类,通过多线程的方式,来控制这段时间。如果在指定时间,如5秒,没有连接上,则中断连接。并做出相应处理。这样,节约了很多的时间。
在这里,我们首先简单介绍一下多线程。
大家都知道,一个进程下面包含,多个线程。线程还分为主线程和后台线程。主线程中断后,后台线程会同时中断,反之,后台线程中断不会影响主线程。多线程编程中,如果没有把线程设置为后台线程,还不能用Abort()方法来中断线程。
我封装了一个叫DbConnConsole的类。用来管理数据库连接超时,并支持多种数据库。
具体代码如下:
2using System.Threading;
3using System.Data;
4using System.Data.SqlClient;
5using Microsoft.Data.Odbc;
6using System.Data.OleDb;
7
8
9namespace DBConnConsole
10{
11
12 /// <summary>
13 /// 数据库类型
14 /// </summary>
15 public enum DatabaseType
16 {
17 SqlServer,
18 Odbc,
19 Oracle,
20 OleDB
21 }
22
23
24
25
26 /// <summary>
27 /// 通过线程控制数据库连接时间管理
28 /// </summary>
29 public class DbConnConsole
30 {
31 private bool bIsConn = false; // 判断连接是否成功
32 private Thread tdConn; // 连接数据库的线程
33 private string strConn = null; // 连接字符串
34 private int nTimeout = 0; // 超时时间
35 private DatabaseType dbType; // 数据库类型
36 private IDbConnection iConn = null; // 数据库连接字符串对象接口
37
38
39 /// <summary>
40 /// 构造函数
41 /// </summary>
42 /// <param name="Conn">连接字符串</param>
43 /// <param name="timeOut">超时时间(毫秒)</param>
44 /// <param name="DBType">数据库类型</param>
45 public DbConnConsole(string Conn, int timeOut, DatabaseType DBType)
46 {
47 strConn = Conn;
48 nTimeout = timeOut;
49 dbType = DBType;
50 }
51
52
53 /// <summary>
54 /// 打开数据库
55 /// </summary>
56 /// <returns>连接对象接口</returns>
57 public IDbConnection Open()
58 {
59 tdConn = new Thread(new ThreadStart(ConnDatabase));
60 Thread tdTimeOut = new Thread(new ThreadStart(ConsoleTimeOut));
61 tdConn.ApartmentState = ApartmentState.MTA;
62 tdConn.IsBackground = true;
63 tdTimeOut.Start();
64 tdTimeOut.Priority = ThreadPriority.Highest;
65 tdConn.Start();
66
67 tdTimeOut.Join(); //连接超时控制线程,不然主线程会直接返回null. !!!!
68 return iConn;
69 }
70
71
72
73 /// <summary>
74 /// 超时控制
75 /// </summary>
76 private void ConsoleTimeOut()
77 {
78 Thread.Sleep(nTimeout);
79 if (bIsConn == false)
80 {
81 tdConn.Abort();
82 tdConn = null;
83 iConn = null;
84 }
85 }
86
87
88 /// <summary>
89 /// 连接数据库
90 /// </summary>
91 private void ConnDatabase()
92 {
93 try
94 {
95
96 //根据数据连接类型创建数据访问类
97 switch (dbType)
98 {
99 case DatabaseType.SqlServer:
100 iConn = new SqlConnection(strConn);
101 iConn.Open();
102 break;
103 case DatabaseType.Odbc:
104 iConn = new OdbcConnection(strConn);
105 iConn.Open();
106 break;
107 case DatabaseType.OleDB:
108 iConn = new OleDbConnection(strConn);
109 iConn.Open();
110 break;
111 }
112
113 bIsConn = true;
114 }
115 catch (Exception exp)
116 {
117 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;"
126 + "user id=sa;pwd=098697;packet size=4096;Connect Timeout=10";
127
128 DbConnConsole dbConsole = new DbConnConsole(strConn, 3000, DatabaseType.SqlServer);
129 IDbConnection iConn = null;
130
131
132 iConn = dbConsole.Open();
133
134 if (iConn != null)
135 {
136
137 string strQuery = "select * from Employees";
138 SqlDataAdapter sqlDA = new SqlDataAdapter(strQuery, (SqlConnection)iConn);
139 DataSet ds = new DataSet();
140 sqlDA.Fill(ds);
141
142 dgTest.DataSource = ds.Tables[0].DefaultView;
143 }
144 else
145 {
146 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.