我无法找到连接池的明确解释。我正在使用从mysql.com下载的.NET连接器构建应用程序。该应用程序只需要一个数据库连接,但将在我的网络上的大约6台机器上同时运行。通常,我会在启动时创建连接,然后离开它。但我看到很多人说这是不好的做法。我也担心超时。我的应用程序将全天候运行,并且可能会有延长的时间段而没有数据库活动。
我倾向于以下内容:
using (MySqlConnection conn = new MySqlConnection(connStr))
{
conn.Open();
// use connection
}
但我不确定我是否理解背景中发生了什么。这实际上是关闭连接并允许gc杀死对象,还是有内置池行为保留对象并在下次尝试创建对象时重新传递它?
我当然不希望每次点击数据库时应用程序都会通过网络重新验证。
有人可以给我一些建议吗?
答案 0 :(得分:0)
.net提供商习惯使用该场景中的连接池。
连接应该在您使用结束时返回池中。
我没有使用mysql探查器查看钩子,但是我的代码依赖于它 - 没有遇到麻烦。
更新:我只是查看了在处理期间完成的调用,它肯定会进行连接池,即最终调用:
internal void CloseFully()
{
if (this.settings.Pooling && this.driver.IsOpen)
{
if ((this.driver.ServerStatus & ServerStatusFlags.InTransaction) != 0)
{
new MySqlTransaction(this, IsolationLevel.Unspecified).Rollback();
}
MySqlPoolManager.ReleaseConnection(this.driver);
}
else
{
this.driver.Close();
}
this.driver = null;
}
更新2 /回答评论: MySqlConnection实例是另一个实例,因为using statement只处理处置(释放资源)。因此,您无需检查其是否已关闭。 MySqlConnection在内部使用其他类/实例,它抓取了适当的实例。这对你的代码是透明的,所以你使用它就像它是一个新的+不同的连接/就像你发布的代码一样。
就像你说的那样,为了能够重用较低级别的连接(在mysql连接器代码中称为Driver),每个池都由连接字符串决定。
答案 1 :(得分:0)
根据this post,连接在关闭之前保持活动并默认为60秒。
答案 2 :(得分:0)
断开连接的模型是全世界使用最多的模型,但不会反复滥用身份验证。
断开连接模式
以下是您希望在大多数时间内断开工作的原因:
此代码:
using(MySqlConnection conn = new MySqlConnection(connStr)) {
if (conn.State == ConnectionState.Closed)
try {
conn.Open();
} catch (MySqlException ex) {
// Exception handling here...
}
// Use of connection here...
}
using关键字用于自动处理在其中实例化的对象,如文章引用所示:
定义一个范围,在该范围之外将放置一个或多个对象。
这样,您可以确保一旦不再需要连接,就可以解决它。所以,是的,一旦再次实例化此连接,将需要新的身份验证,因为它不再存在。在这里进行了一些短暂的轮询,但这不是你需要担心的事情。
连接模式
为确保在整个应用程序中仅使用一个此类连接,您应将其用作singleton。但是,一旦连接字符串发生更改,有一天您必须确保所有应用程序都关闭并重新打开,以便此连接获得刷新的连接字符串。这不可行,但我不知道你的背景。
使用企业库数据访问应用程序阻止
为了使您的连接池易于管理,您可能需要使用Enterprise Library Data Access Application Block。
DAAB是一个易于使用,完全可配置的数据访问层,由Microsoft工程师和其他参与公司设计。然后,管理连接池可以像1-2-3一样简单!
我认为使用DAAB可以获得很多收益,DAAB可以在XML文件中完全配置,并且需要非常低的维护。
编辑如果我可以进一步推动,我或许会考虑将Façade设计模式与工厂一起使用。
有效使用Facade和工厂设计模式
拥有“智能”外观,正是这样能为您提供所需的连接。因此,这是一个简单的例子(假设您有一个名为“DefaultConnectionString”的项目设置):
public static class ApplicationFacade {
private static readonly ApplicationFactory _applicationFactory = new ApplicationFactory();
public static DefaultConnectionString {
get {
return Properties.Settings.Default.DefaultConnectionString;
}
}
public static IList<ICustomer> GetCustomers() {
using(var connection = OpenConnection())
_applicationFactory.GetCustomers(connection);
}
public MySqlConnection OpenConnection() {
var newConnection = new MySqlConnection(DefaultConnectionString);
try {
newConnection.Open();
} catch (Exception ex) {
// Exception handling...
}
return newConnection;
}
}
internal sealed class ApplicationFactory {
internal ApplicationFactory() {
}
internal IList<ICustomer> GetCustomers(MySqlConnection connection) {
if (connection.State != ConnectionState.Open)
throw new InvalidOperationException()
IList<ICustomer> customers = new List<ICustomer>();
var command = new MySqlCommand(connection, @"select * from Customers");
// Place code to get customers here...
return customers;
}
}
// So you'll be able to use share the same connection throught your factory whenever needed, preventing the overkill of authentication over and over again. Here's how this would be used:
public partial class MainForm : Form {
private void PopulateGrid() {
dataGridView1.DataSource = ApplicationFacade.GetCustomers();
// And you never care about the connection! All you want is the list of customers, that's all!
}
}
这是我经常在我的开发项目中使用的模式。它允许我的类库中的单个入口点,并且它们非常易于使用。
嗯,这可能比你要求的更多,但我希望它有所帮助。