数据库连接释放问题

“超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。”

一看就是数据库连接池满了,应该是打开后没有释放的原因,但是我的Connection对象都使用using及时释放了,怎么会出现这种情况呢?花了很长时间终于到了原因,所以写下来记录一下。

扩展小知识:

--查询数据库的连接情况:(数据库SQL可直接执行)

SELECT [dec].client_net_address,

[des].[program_name],

[des].[host_name],

Count([dec].session_id) AS connection_count

FROM sys.dm_exec_sessions AS [des]

INNER JOIN sys.dm_exec_connections AS [dec]

ON [des].session_id = [dec].session_id

GROUP BY [dec].client_net_address,

[des].[program_name],

[des].[host_name]

ORDER BY [des].[program_name],

[dec].[client_net_address]

项目代码:

//创建连接对象的工厂类

public class ConnectionFactory

{

private static readonly string connString = ConfigurationManager.ConnectionStrings["SQLServerDatabase"].ConnectionString;

public static IDbConnection CreateConnection()

{

IDbConnection conn = new SqlConnection(connString);

conn.Open();

return conn;

}

}

//UserInfoDAL类

public class UserInfoDAL:IDAL.IUserInfoDAL

{

private IDbConnection _conn;

public IDbConnection Conn

{

get

{

//工厂实例化一个连接对象

return _conn = ConnectionFactory.CreateConnection();

}

}

//根据id获取entity

public UserInfo GetEntity(string id)

{

using (Conn)

{

string query = "select * from UserInfo where UserInfo_id = @UserInfo_id";

//使用dapper

return userInfo = Conn.Query(query, new { UserInfo_id = id }).SingleOrDefault();

}

}

}

代码基本上就是上面的形式,好像也没有什么不对的地方。下面就来调试一下。首先创建一个单元测试:

[TestMethod]

public void TestConnectionCount()

{

SQLServerDAL.UserInfoDAL userInfoDAL = new SQLServerDAL.UserInfoDAL();

Model.UserInfo userInfo = userInfoDAL.GetEntity("3");

userInfo = userInfoDAL.GetEntity("3");

userInfo = userInfoDAL.GetEntity("3");

userInfo = userInfoDAL.GetEntity("3");

}

发现原因是因为get的使用不当后,就干脆不用get了,目前的解决方案为:

public class UserInfoDAL:IDAL.IUserInfoDAL

{

public IDbConnection Conn;

public UserInfo GetEntity(string id)

{

using (Conn=ConnectionFactory.CreateConnection())

{

string query = "select * from UserInfo where UserInfo_id = @UserInfo_id";

return Conn.Query(query, new { UserInfo_id = id }).SingleOrDefault();

}

}

}