注:靠.net GC是无法释放完全 SqlConnection 对象的,如果你不停的 new SqlConnection,最后不同时调用 Close & Dispose,过不了多久,程序就会报“连接池已满”类似的错误。
一般有以下用法:
1、需要使用时 new SqlConnection & Open,使用完后 Close & Dispose,这种是最简单的,但是,性能不多说(有可能一个页面需要做100次重复操作)。
如果有人使用 ExecuteReader 方法的话(未读完数据不能关闭 Connection),项目庞大以后,这时如果有一处忘了 Close & Dispose,可能会影响系统的正常运行。
因为每次都是 new SqlConnection,所以不能扩展事务。
2、添加页面对象 SqlConnection,一直 Open,页面访问结束时 Close & Dispose,性能较好,但是,灵活性差,程序结构也变得难看。
可以扩展事务。
注:以上我都不是说直接在页面上写 SqlConnection 方法。
如果能有一个类来专门管理 SqlConnection,使用时从类里拿,使用完后归还,无须过多考虑性能,这样多好?
用户被次访问 web 都会被分配到某一线程来执行请求,这样我就可以建立一个静态全局对象来保存 SqlConnection,采集 Dictionary<int, SqlConnection> 类型,按线程ID来标识 key
这样还不够,如果需要支持单线程同时打开多个 SqlConnection,我们必须要把类型改成 Dictionary<int, List<SqlConnection>>,代码实现如下:
代码
private static Dictionary<int, List<SqlConnection>> _connectionPool = new Dictionary<int, List<SqlConnection>>();
private static string _connectionString = "xxxx";
public static SqlConnection GetConnection() {
SqlConnection conn = null;
int tid = Thread.CurrentThread.ManagedThreadId; //线程标识
if (!_connectionPool.ContainsKey(tid)) _connectionPool.Add(tid, new List<SqlConnection>());
conn = _connectionPool[tid].Find(delegate(SqlConnection conn) {
return conn.SqlConnection != null && conn.SqlConnection.State == ConnectionState.Closed;
});
if (conn == null) {
conn = new SqlConnection(_connectionString);
_connectionPool[tid].Add(conn);
}
return conn;
}
当用户需要链接时,使用 ConnectionManager.GetConnection() 即可,无须过多考虑回收等问题。当然,上面代码段并没有实现自动回收,即帮程序员释放(Close)忘记关闭的 SqlConnection 功能。我把完整代码发出来,有兴趣的可以看看,讨论讨论,欢迎拍砖!
目前俺使用此类 + SqlHelper已经实现了N层架构的事务控制!
如下代码:
SqlHelper.BeginTransaction(); //开始事务
NewsInfo news = News.Insert(xxx,xxx,xxx);
Admin.Update(admin);
//SqlHelper.CommitTransaction(); //提交
SqlHelper.RollbackTransaction(); //回滚
//即使程序员忘记提交事务了,系统会在10秒后的第一次访问数据库前提交!
同样借用了按线程来做事务的思想,我觉得最爽的是还增强了自动提交(回收资源)事务功能(比如某程序员忘掉提交事务的),这样系统不会因为这样的马虎而崩溃!
转载请注明来自: http://www.caodong.net/Article/263.html