0

我很难找到关于连接池的清晰解释。我正在使用从 mysql.com 下载的 .NET 连接器构建应用程序。该应用程序只需要一个数据库连接,但将在我的网络上大约 6 台机器上同时运行。通常,我会在启动时创建连接并离开它。但是我看到很多人说这是不好的做法。我也担心超时。我的应用程序将 24/7 全天候运行,并且可能会在很长一段时间内没有数据库活动。

我倾向于以下:

using (MySqlConnection conn = new MySqlConnection(connStr))
{
    conn.Open();
    // use connection
}

但我不确定我是否理解后台发生的事情。这实际上是关闭连接并允许 gc 杀死对象,还是有一个内置的池行为可以保留对象并在我下次尝试创建对象时重新传递它?

我当然不希望应用程序在每次访问数据库时都通过网络重新进行身份验证。

谁能给我一些建议?

4

3 回答 3

0

在这种情况下,.net 提供商习惯使用连接池。

连接应该在您使用结束时返回到池中。

我没有使用 mysql 分析器查看钩子,但我有依赖它的代码 - 没有遇到问题。

更新:我只是查看了 dispose 期间完成的调用,它肯定会进行连接池,即它最终调用:

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 语句只处理处置(释放资源)。因此,您无需检查它是否已关闭。MySqlConnection 在内部使用其他类/实例,即它获取适当的实例。这对您的代码是透明的,因此您可以像使用新的+不同的连接一样使用它/就像在您发布的代码中一样。

就像你说的那样,为了能够重用较低级别的连接(在mysql连接器代码中称为Driver),每个池都由连接字符串确定。

于 2010-05-13T18:30:20.600 回答
0

根据这篇文章,连接在关闭之前默认保持活动状态和池化 60 秒。

于 2010-05-13T18:30:50.087 回答
0

断开连接的模型是全世界使用最多的模型,但不会一遍又一遍地滥用身份验证。

断开模式

以下是您希望大部分时间不联网工作的一些原因:

  1. 为您的数据库服务器购买的 CLA(客户端许可协议)的数量(好吧,这里并不适用,因为它是 MySQL);
  2. 如果一次连接的人太多,这会降低 DBE(数据库引擎)的速度;
  3. 保持连接打开使网络保持繁忙,网络太忙更容易失败;
  4. 当用户在编辑时,比如说一个客户的详细信息,他不需要保留他与数据库服务器的连接,并且可能锁定一行或一个数据表,这会导致大的并发锁定问题。

这段代码:

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关键字用于自动处理在其中实例化的对象,如文章参考所述:

定义一个范围,一个或多个对象将被释放到该范围之外。

这样,您可以确保一旦不再需要连接,您就可以将其丢弃。所以是的,一旦再次实例化此连接,将需要新的身份验证,因为它不再存在。有一小段时间在这里完成了一些民意调查,但这没什么你需要担心的。

连接模式

为了确保在整个应用程序中只使用一个这样的连接,您应该将其用作单例。但是,一旦您的连接字符串更改,总有一天,您必须确保所有应用程序都关闭并重新打开,以便此连接获得刷新的连接字符串。这是不可行的,但我不知道你的背景。

使用企业图书馆数据访问应用程序块

为了使您的连接池易于管理,您可能需要使用Enterprise Library Data Access Application Block

DAAB 是一个易于使用、完全可配置的数据访问层,由 Microsoft 工程师和其他参与公司设计。然后,管理连接池可以像 1-2-3 一样简单!

我认为您可以使用 DAAB 获得很多收益,该 DAAB 可以在 XML 文件中完全配置并且需要非常低的维护。

编辑如果我可以更进一步,我可能会考虑使用带有工厂的外观设计模式。

有效地使用外观和工厂设计模式

拥有“智能”外观,正是它为您提供所需的连接。因此,这是一个简单的示例(假设您有一个名为“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!
    }
}

这是我在开发项目中经常使用的模式。它允许我的类库有一个入口点,而且它们非常易于使用。

好吧,这可能比您要求的要多,但我希望它有所帮助。

于 2010-05-13T18:48:56.660 回答