讨论:Codematic代码生成器的性能问题(散分)
最近我公司开发一套中型网站系统,数据访问层和业务逻辑层采用了李天平先生的Codematic1.1代码生成系统。但是在项目实际运行过程中我发现只要同时在线的人数达到100多的时候就会产生死锁,当然我还无法确定死锁产生的原因是由于这个数据访问层导致的,目前只是对这种写法有所怀疑,由于我个人对.net的知识掌握不深,但仔细研究了codematic的三层代码之后我觉得他的数据访问层和业务逻辑层好象有些不妥,虽然在测试的环境下看不出来,所以想到李天平先生的论坛(bbs.maticsoft.com)去讨论,无奈该论坛已经停止注册了,希望能在这里进行讨论,在讨论的过程中能学习到更多的知识。如果李天平先生看到这篇讨论,请原谅我的行为,我个人纯粹是站在技术的角度来提出这次讨论,并没有对李先生不敬的意思。
相关资料:李天平先生的数据访问层DbHelperSQL.cs http://download.csdn.net/user/salifei/ 刚上传完毕,要过段时间才能下载
Maticsoft网站 http://www.maticsoft.com 该站点有1.1和2.0两种版本的代码生成机下载,2.0版本尚未完成
讨论对象:我们的讨论以1.1版的DbHelperSQL(以下简称为DBHS)为对象。
讨论问题:1.DBHS的连接池泄露问题。
2.DBHS的连接并发问题。
我的个人分析:
1.关于连接池泄露:
在DBHS中大多数的方法所用到的Connection都有using关键字限定作用域,也就是说这些方法中不会产生连接池中的连接泄露,但是所有返回值为SqlDataReader的方法都没有使用using关键字,这么做是正确的,因为SqlDataReader只有在连接到数据库的状态下才能读取数据,这一点是与DataSet不同,在DBHS中的一个例子:
/// <summary>
/// 执行查询语句,返回SqlDataReader
/// </summary>
/// <param name= "strSQL "> 查询语句 </param>
/// <returns> SqlDataReader </returns>
public static SqlDataReader ExecuteReader(string strSQL)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(strSQL,connection);
try
{
connection.Open();
SqlDataReader myReader = cmd.ExecuteReader(); //注意这一行
return myReader;
}
catch(
System.Data.SqlClient.SqlException e)
{
throw new Exception(e.Message);
}
}
在这个例子中该ExecuteReader没有使用参数CommandBehavior.CloseConnection,这里会导致连接池泄露的问题,假定在业务逻辑层使用该方法获取了某个SqlDataReader,该SqlDataReader使用完毕Close()之后,应该是不会关闭所使用的Connection,并且也没有其他方式能够关闭这个Connection,于是该连接被泄露,由于数据库连接资源是非托管资源,垃圾回收器也无法关闭这样的连接。
还是这个例子,在错误处理部分也没有关闭Connection,也就是说如果传入的SQL语句导致该方法出错,这个连接一样会泄露掉。
同样的问题在这个类中有3处存在,分别是ExecuteReader(string strSQL)、SqlDataReader ExecuteReader(string SQLString,params SqlParameter[] cmdParms)、RunProcedure(string storedProcName, IDataParameter[] parameters )
------解决方案--------------------我也看过CODEMATIC,也用过,
最让人烦的是,居然没设基层接口,后来就没用了
------解决方案--------------------新人最好别用这些代码生成工具,这样会影响你能力的提升的。
------解决方案--------------------我现在用自己写的codesmith模版
------解决方案--------------------应该不是Codematic的问题,他那个SqlDataReader的函数没有问题,微软的企业库差不多也是这样设计的,不过你自己要注意及时关闭datareader,如果不放心的话,可以返回dataset.猜十有八九是你自己SQL语句有问题,仔细检查
------解决方案--------------------