C# 需要帮助管理MySql连接吗

C# 需要帮助管理MySql连接吗,c#,mysql,connection,pooling,C#,Mysql,Connection,Pooling,我很难找到连接池的清晰解释。我正在使用从mysql.com下载的.NET连接器构建一个应用程序。该应用程序只需要一个db连接,但将在我网络上的大约6台机器上同时运行。通常,我会在启动时创建连接,然后离开它。但是我看到很多人发帖子说这是不好的做法。我还担心超时。我的应用程序将全天候运行,可能会有较长时间没有数据库活动 我倾向于以下几点: using (MySqlConnection conn = new MySqlConnection(connStr)) { conn.Open();

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

我倾向于以下几点:

using (MySqlConnection conn = new MySqlConnection(connStr))
{
    conn.Open();
    // use connection
}
但我不确定我是否理解背景中发生的事情。这实际上是在关闭连接并允许gc终止对象,还是存在一种内置的池行为来保留对象并在下次尝试创建对象时重新交付它

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


有谁能给我一些建议吗?

在那种情况下,.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实例是另一个实例,因为它只处理处置(释放资源)。因此,您不需要检查它是否已关闭。MySqlConnection在内部使用其他类/实例,也就是说,它获取相应的实例。这对你的代码是透明的,所以你使用它就像它是一个新的+不同的连接/就像你发布的代码一样


正如您所说,为了能够重用较低级别的连接(在mysql连接器代码中称为驱动程序),每个池由连接字符串确定。

根据连接,在关闭之前,默认情况下,连接保持活动状态并池化60秒。

断开连接的模型是世界上使用最多的,虽然没有一次又一次地滥用身份验证

断开模式

以下是您希望在大多数时间不连接的情况下工作的一些原因:

  • 为您的数据库服务器购买的CLA(客户端许可协议)的数量(好吧,这里不太适用,因为它是MySQL)
  • 如果一次连接的人太多,这会减慢DBE(数据库引擎)的速度
  • 保持连接打开会使网络繁忙,而过于繁忙的网络更有可能失败
  • 当用户在编辑(比如说客户详细信息)时,他不需要保留与数据库服务器的连接,也不需要锁定行或数据表,这将导致严重的并发锁定问题
  • 此代码:

    using(MySqlConnection conn = new MySqlConnection(connStr)) {
        if (conn.State == ConnectionState.Closed)
            try {
                conn.Open();
            } catch (MySqlException ex) {
                // Exception handling here...
            }
        // Use of connection here...
    }
    
    关键字用于自动处理其中实例化的对象,如文章引用所述:

    定义一个作用域,在该作用域之外将处理一个或多个对象

    通过这种方式,您可以确保一旦不再需要连接,就可以解除连接。因此,是的,一旦再次实例化此连接,将需要新的身份验证,因为它不再存在。在短时间内,这里会进行一些民意调查,但这没什么好担心的

    连接模式

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

    使用企业库数据访问应用程序块

    为了使连接池易于管理,您可能需要使用

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

    我认为使用DAAB可以获得很多好处,它在XML文件中是完全可配置的,并且需要非常低的维护

    <>强>编辑< /强>如果我可以再推一点,我可能会考虑使用工厂的FAXAID设计模式。

    有效使用立面和工厂设计模式

    拥有一个“智能”的外表,正是它为你提供了你所需要的连接。因此,这里有一个简单的示例(假设您有一个名为“DefaultConnectionString”的项目设置):

    公共静态类ApplicationFacade{
    私有静态只读ApplicationFactory _ApplicationFactory=new ApplicationFactory();
    公共静态DefaultConnectionString{
    得到{
    返回Properties.Settings.Default.DefaultConnectionString;
    }
    }
    公共静态IList GetCustomers(){
    使用(var connection=OpenConnection())
    _applicationFactory.GetCustomers(连接);
    }
    公共MySqlConnection OpenConnection(){
    var newConnection=newmysqlconnection(DefaultConnectionString);
    试一试{
    newConnection.Open();
    }捕获(例外情况除外){
    //异常处理。。。
    }
    返回新连接;
    }
    }
    内部密封类应用程序工厂{
    内部应用程序工厂(){
    }
    内部IList GetCustomers(MySqlConnection连接){
    if(connection.State!=ConnectionState.Open)
    抛出新的InvalidOperationException()
    IList customers=新列表();
    var命令=新的MySqlCommand(连接,@“从客户选择*);
    //在此处放置代码以获取客户。。。
    返回c
    
    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!
        }
    }