需要帮助管理MySql连接

时间:2010-05-13 18:20:53

标签: c# mysql connection pooling

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

我倾向于以下内容:

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

但我不确定我是否理解背景中发生了什么。这实际上是关闭连接并允许gc杀死对象,还是有内置池行为保留对象并在下次尝试创建对象时重新传递它?

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

有人可以给我一些建议吗?

3 个答案:

答案 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)

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

断开连接模式

以下是您希望在大多数时间内断开工作的原因:

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

    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!
        }
    }
    

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

    嗯,这可能比你要求的更多,但我希望它有所帮助。