有人建议我重新安排我的代码以“汇集”我的ADO连接。在每个网页上,我将打开一个连接并继续使用相同的开放连接。但有人 else 告诉我,这在10年前很重要,但现在并不那么重要。如果我制作,比方说,在网上发布5个db调用,使用我打开/关闭的5个独立连接是否有问题?
答案 0 :(得分:3)
如果您将ADO.NET与SQL Server一起使用,那么您的连接可能已经合并。现在,连接池是数据库中非常常见的做法,并且大多数时候您在不知情的情况下使用池。我的猜测是你被告知手动汇集连接并不重要,因为它现在通常是自动的。
这是一个很好的做法,原因有两个。首先,创建连接需要一定的时间,不断关闭和打开您的连接可能会浪费宝贵的时间。其次,连接通常是有限的资源,不应浪费它们。通常,堆栈级限制也可以防止连接打开的频率。在高吞吐量环境中,实际打开和关闭连接可能会占用有限的资源,并在它们再次慢慢可用时产生瓶颈。
答案 1 :(得分:3)
从框架2.0,ASP.NET默认将池连接到SQL Server。
然而,你所谈论的人所谈论的并不完全是汇集。相反,它是关于减少数据库会话的数量。
当连接汇集时,关闭连接对象并打开另一个连接对象的代价非常小。通常发生的是数据库连接本身返回到连接池,当您创建下一个连接对象时,它只是使用您刚刚返回的相同连接重新建立数据库连接。
但是,由于每次重新建立连接时都会向数据库发出请求,因此如果合理可能,应尝试减少使用的连接对象的数量。
页面循环使得为所有数据库操作保持连接对象打开有点困难,所以我通常做的是使用一个连接对象来定期获取在Page_Load中完成的数据,然后使用另一个连接(如果需要的话)例如,在按钮事件中更新数据库中的数据。
答案 2 :(得分:3)
SQL Server的连接自动在ASP.NET应用程序中汇集:每个不同的连接字符串有一个池。如果您遵循最佳实践并将数据库代码隐藏在整个应用程序中连接字符串不变的DAL中,那么您将始终使用单个连接对象池。
那么这对您的数据库方法意味着什么呢?好吧,首先,它意味着“关闭连接”实际上转换为“返回到池的连接”,而不是真正关闭应用程序到SQL Server的链接。因此,关闭和重新开放并不是那个很重要的交易。然而,话虽如此,这里有一些最佳实践。
首先,即使您的应用程序显着扩展,您也不希望池中的连接用尽。也就是说,永远不要反思“本页面上的用户” - 用“千人使用此页面”来思考。
其次,尽管关闭并重新打开连接并不是很费力,但您通常希望尽可能打开延迟连接,使用它直到完成然后关闭它尽可能早期。唯一的例外是,如果您有一个耗时的过程,在检索一些数据后 保存或检索其他数据之前。
第三,我强烈建议不要在页面生命周期的早期打开连接,并在生命周期的后期以不同的方法关闭它。为什么?因为你可以做的最差事情是保持连接打开,因为你忘记添加逻辑来关闭它。是的,当GC启动时,他们最终将被关闭,但是,如果你正在考虑“使用这个页面的数千人*真正的麻烦的机会变得明显。
现在,如果你说确定你关闭了连接,因为你总是在某个关键的逻辑点(例如Page_Unload方法)中这样做。好吧,只要你能自信地说你永远不会抛出跳出页面生命周期的错误,这就是很好的。你不能这样做。所以...不要在页面生命周期的一种方法中打开,而在另一种方法中关闭。
最后,我强烈建议实现管理数据库连接的DAL,并提供处理数据的工具。最重要的是,构建一个业务逻辑层(BLL),使用这些工具为UI提供类型安全的对象(例如“模型”对象)。如果使用IDisposable接口实现BLL对象,则始终可以使用范围确保Connection安全性。它还允许您在非常短时间内保持数据库连接打开:只需打开BLL对象,将数据拉入本地对象或列表,然后关闭BLL对象(离开范围)。然后,您可以在连接关闭后使用BLL 返回的数据。
所以......这看起来像什么。那么,在您的 Pages (UI)上,您将使用这样的业务逻辑类:
using (BusinessLogicSubClass bLogic = new BusinessLogicSubClass())
{
// Retrieve and display data or pull from your UI and update
// using methods built into the bLogic object
.
.
.
} // <-- Going out of scope will automatically call the dispose method and close the database connection.
您的BusinessLogicSubClass将派生自实现IDisposable的BusinessLogic对象。它将实例化您的DAL类并打开如下连接:
public class BusinessLogic : IDisposable
{
protected DBManagementClass qry;
public BusinessLogic()
{
qry = new DBManagementClass();
}
public void Dispose()
{
qry.Dispose(); <-- qry does the connection management as described below.
}
... other methods that work with the qry class to
... retrieve, manipulate, update, etc. the data
... Example: returning a List<ModelClass> to the UI ...
}
当BusinessLogic类超出范围时,将自动调用Dispose方法,因为它实现了IDisposable接口。
您的DAL课程将采用匹配的方法:
public class DBManagementClass : IDisposable
{
public static string ConnectionString { get; set; } // ConnectionString is initialized when the App starts up.
public DBManagementClass()
{
conn = new SqlConnection(ConnectionString);
conn.Open();
}
public void Dispose()
{
conn.Close();
}
... other methods
}
鉴于我到目前为止所描述的内容,DAL不 是IDisposable。但是,当我测试新的BLL方法时,我在测试代码中广泛使用了我的DAL类,因此我将DAL构造为IDisposable,因此我可以在测试期间使用“using”构造。
遵循这种方法,实质上,您将永远不必再考虑连接池。
答案 3 :(得分:2)
我想说将连接汇集到任何东西都是个好主意。几乎所有东西都有一个有限的连接限制。此外,打开连接会产生开销,因此使用相同的连接会更有效并节省响应时间。
如果扩展到15个数据库调用怎么办?那些联系开始堆积起来。
池'他们。没有理由不这样做。
当然,服务器现在可以解决任何问题,但是你可以节省的响应时间可以改善用户的体验。
答案 4 :(得分:2)
ADO.NET通常会将您的连接汇集在一起。这有时被认为是一件好事;它努力做正确的事情,可能不会引起任何悲伤。
除了每次创建具有相同参数的连接之外,您不需要做任何特殊的事情(这并不困难,只需使用相同的例程在每个页面上创建连接)。
当然,池连接可以导致特殊情况下的困难,在这种情况下,您可能希望禁用它们。但除此之外,只要把它放在一边就可以了。它应该有效。
答案 5 :(得分:1)
我发现的关键是创建数据库连接需要多长时间。
对于在世界中途缓慢连接的MSSQL Server,池化将显着提高应用程序的响应能力。
对于本地MySQL安装,您可能看不到显着差异。