使用 ConnectionManager 来管理 SqlConnection 的一些想法


注:靠.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